commit 757fdc2454a97890c119cca8662b8d1763265e9a Author: dscho Date: Wed Aug 1 11:52:01 2001 +0000 Initial revision diff --git a/.DS_Store b/.DS_Store new file mode 100755 index 0000000..c1a387f Binary files /dev/null and b/.DS_Store differ diff --git a/.depend b/.depend new file mode 100755 index 0000000..dd6ed1c --- /dev/null +++ b/.depend @@ -0,0 +1,369 @@ +main.o: main.c /usr/include/stdio.h /usr/include/features.h \ + /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/stddef.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/stdarg.h \ + /usr/include/bits/types.h /usr/include/libio.h \ + /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ + /usr/include/stdlib.h /usr/include/sys/types.h /usr/include/time.h \ + /usr/include/endian.h /usr/include/bits/endian.h \ + /usr/include/sys/select.h /usr/include/bits/select.h \ + /usr/include/bits/sigset.h /usr/include/sys/sysmacros.h \ + /usr/include/alloca.h /usr/include/errno.h /usr/include/bits/errno.h \ + /usr/include/linux/errno.h /usr/include/asm/errno.h \ + /usr/include/sys/socket.h /usr/include/bits/socket.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/limits.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/syslimits.h \ + /usr/include/limits.h /usr/include/bits/posix1_lim.h \ + /usr/include/bits/local_lim.h /usr/include/linux/limits.h \ + /usr/include/bits/posix2_lim.h /usr/include/bits/sockaddr.h \ + /usr/include/asm/socket.h /usr/include/asm/sockios.h \ + /usr/include/netinet/in.h /usr/include/stdint.h \ + /usr/include/bits/wordsize.h /usr/include/bits/in.h \ + /usr/include/bits/byteswap.h /usr/include/unistd.h \ + /usr/include/bits/posix_opt.h /usr/include/bits/confname.h \ + /usr/include/getopt.h /usr/include/signal.h \ + /usr/include/bits/signum.h /usr/include/bits/siginfo.h \ + /usr/include/bits/sigaction.h /usr/include/bits/sigcontext.h \ + /usr/include/asm/sigcontext.h /usr/include/bits/sigstack.h rfb.h \ + include/Xserver/scrnintstr.h include/Xserver/screenint.h \ + include/Xserver/misc.h include/X11/Xosdefs.h include/X11/Xfuncproto.h \ + include/X11/Xmd.h include/X11/X.h include/Xserver/os.h \ + include/X11/Xalloca.h /usr/include/string.h include/X11/Xfuncs.h \ + include/Xserver/miscstruct.h include/X11/Xprotostr.h \ + include/Xserver/region.h include/Xserver/regionstr.h \ + include/Xserver/pixmap.h include/Xserver/gc.h include/X11/Xproto.h \ + include/Xserver/colormap.h include/Xserver/window.h \ + include/Xserver/cursor.h include/Xserver/validate.h \ + include/Xserver/dix.h include/Xserver/input.h rfbproto.h \ + libvncauth/vncauth.h +rfbserver.o: rfbserver.c /usr/include/stdio.h /usr/include/features.h \ + /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/stddef.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/stdarg.h \ + /usr/include/bits/types.h /usr/include/libio.h \ + /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ + /usr/include/stdlib.h /usr/include/sys/types.h /usr/include/time.h \ + /usr/include/endian.h /usr/include/bits/endian.h \ + /usr/include/sys/select.h /usr/include/bits/select.h \ + /usr/include/bits/sigset.h /usr/include/sys/sysmacros.h \ + /usr/include/alloca.h /usr/include/unistd.h \ + /usr/include/bits/posix_opt.h /usr/include/bits/confname.h \ + /usr/include/getopt.h /usr/include/pwd.h /usr/include/sys/socket.h \ + /usr/include/bits/socket.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/limits.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/syslimits.h \ + /usr/include/limits.h /usr/include/bits/posix1_lim.h \ + /usr/include/bits/local_lim.h /usr/include/linux/limits.h \ + /usr/include/bits/posix2_lim.h /usr/include/bits/sockaddr.h \ + /usr/include/asm/socket.h /usr/include/asm/sockios.h \ + /usr/include/netinet/in.h /usr/include/stdint.h \ + /usr/include/bits/wordsize.h /usr/include/bits/in.h \ + /usr/include/bits/byteswap.h /usr/include/arpa/inet.h rfb.h \ + include/Xserver/scrnintstr.h include/Xserver/screenint.h \ + include/Xserver/misc.h include/X11/Xosdefs.h include/X11/Xfuncproto.h \ + include/X11/Xmd.h include/X11/X.h include/Xserver/os.h \ + include/X11/Xalloca.h /usr/include/string.h include/X11/Xfuncs.h \ + include/Xserver/miscstruct.h include/X11/Xprotostr.h \ + include/Xserver/region.h include/Xserver/regionstr.h \ + include/Xserver/pixmap.h include/Xserver/gc.h include/X11/Xproto.h \ + include/Xserver/colormap.h include/Xserver/window.h \ + include/Xserver/cursor.h include/Xserver/validate.h \ + include/Xserver/dix.h include/Xserver/input.h rfbproto.h \ + libvncauth/vncauth.h +miregion.o: miregion.c /usr/include/stdio.h /usr/include/features.h \ + /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/stddef.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/stdarg.h \ + /usr/include/bits/types.h /usr/include/libio.h \ + /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ + /usr/include/stdlib.h /usr/include/sys/types.h /usr/include/time.h \ + /usr/include/endian.h /usr/include/bits/endian.h \ + /usr/include/sys/select.h /usr/include/bits/select.h \ + /usr/include/bits/sigset.h /usr/include/sys/sysmacros.h \ + /usr/include/alloca.h include/Xserver/miscstruct.h \ + include/Xserver/misc.h include/X11/Xosdefs.h include/X11/Xfuncproto.h \ + include/X11/Xmd.h include/X11/X.h include/Xserver/os.h \ + include/X11/Xalloca.h /usr/include/string.h include/X11/Xfuncs.h \ + include/X11/Xprotostr.h include/Xserver/regionstr.h \ + include/Xserver/gc.h include/X11/Xproto.h include/Xserver/screenint.h \ + include/Xserver/pixmap.h +auth.o: auth.c /usr/include/stdio.h /usr/include/features.h \ + /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/stddef.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/stdarg.h \ + /usr/include/bits/types.h /usr/include/libio.h \ + /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ + /usr/include/stdlib.h /usr/include/sys/types.h /usr/include/time.h \ + /usr/include/endian.h /usr/include/bits/endian.h \ + /usr/include/sys/select.h /usr/include/bits/select.h \ + /usr/include/bits/sigset.h /usr/include/sys/sysmacros.h \ + /usr/include/alloca.h rfb.h include/Xserver/scrnintstr.h \ + include/Xserver/screenint.h include/Xserver/misc.h \ + include/X11/Xosdefs.h include/X11/Xfuncproto.h include/X11/Xmd.h \ + include/X11/X.h include/Xserver/os.h include/X11/Xalloca.h \ + /usr/include/string.h include/X11/Xfuncs.h \ + include/Xserver/miscstruct.h include/X11/Xprotostr.h \ + include/Xserver/region.h include/Xserver/regionstr.h \ + include/Xserver/pixmap.h include/Xserver/gc.h include/X11/Xproto.h \ + include/Xserver/colormap.h include/Xserver/window.h \ + include/Xserver/cursor.h include/Xserver/validate.h \ + include/Xserver/dix.h include/Xserver/input.h rfbproto.h \ + libvncauth/vncauth.h /usr/include/netinet/in.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/limits.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/syslimits.h \ + /usr/include/limits.h /usr/include/bits/posix1_lim.h \ + /usr/include/bits/local_lim.h /usr/include/linux/limits.h \ + /usr/include/bits/posix2_lim.h /usr/include/stdint.h \ + /usr/include/bits/wordsize.h /usr/include/bits/socket.h \ + /usr/include/bits/sockaddr.h /usr/include/asm/socket.h \ + /usr/include/asm/sockios.h /usr/include/bits/in.h \ + /usr/include/bits/byteswap.h +sockets.o: sockets.c /usr/include/stdio.h /usr/include/features.h \ + /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/stddef.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/stdarg.h \ + /usr/include/bits/types.h /usr/include/libio.h \ + /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ + /usr/include/sys/types.h /usr/include/time.h /usr/include/endian.h \ + /usr/include/bits/endian.h /usr/include/sys/select.h \ + /usr/include/bits/select.h /usr/include/bits/sigset.h \ + /usr/include/sys/sysmacros.h /usr/include/sys/time.h \ + /usr/include/bits/time.h /usr/include/sys/socket.h \ + /usr/include/bits/socket.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/limits.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/syslimits.h \ + /usr/include/limits.h /usr/include/bits/posix1_lim.h \ + /usr/include/bits/local_lim.h /usr/include/linux/limits.h \ + /usr/include/bits/posix2_lim.h /usr/include/bits/sockaddr.h \ + /usr/include/asm/socket.h /usr/include/asm/sockios.h \ + /usr/include/netinet/in.h /usr/include/stdint.h \ + /usr/include/bits/wordsize.h /usr/include/bits/in.h \ + /usr/include/bits/byteswap.h /usr/include/netinet/tcp.h \ + /usr/include/netdb.h /usr/include/rpc/netdb.h /usr/include/fcntl.h \ + /usr/include/bits/fcntl.h /usr/include/errno.h \ + /usr/include/bits/errno.h /usr/include/linux/errno.h \ + /usr/include/asm/errno.h /usr/include/unistd.h \ + /usr/include/bits/posix_opt.h /usr/include/bits/confname.h \ + /usr/include/getopt.h /usr/include/pthread.h /usr/include/sched.h \ + /usr/include/bits/sched.h /usr/include/signal.h \ + /usr/include/bits/pthreadtypes.h /usr/include/bits/sigthread.h rfb.h \ + include/Xserver/scrnintstr.h include/Xserver/screenint.h \ + include/Xserver/misc.h include/X11/Xosdefs.h include/X11/Xfuncproto.h \ + include/X11/Xmd.h include/X11/X.h include/Xserver/os.h \ + include/X11/Xalloca.h /usr/include/string.h include/X11/Xfuncs.h \ + include/Xserver/miscstruct.h include/X11/Xprotostr.h \ + include/Xserver/region.h include/Xserver/regionstr.h \ + include/Xserver/pixmap.h include/Xserver/gc.h include/X11/Xproto.h \ + include/Xserver/colormap.h include/Xserver/window.h \ + include/Xserver/cursor.h include/Xserver/validate.h \ + include/Xserver/dix.h include/Xserver/input.h rfbproto.h \ + libvncauth/vncauth.h +xalloc.o: xalloc.c include/X11/Xos.h include/X11/Xosdefs.h \ + /usr/include/sys/types.h /usr/include/features.h \ + /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \ + /usr/include/bits/types.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/stddef.h \ + /usr/include/time.h /usr/include/endian.h /usr/include/bits/endian.h \ + /usr/include/sys/select.h /usr/include/bits/select.h \ + /usr/include/bits/sigset.h /usr/include/sys/sysmacros.h \ + /usr/include/string.h /usr/include/fcntl.h /usr/include/bits/fcntl.h \ + /usr/include/unistd.h /usr/include/bits/posix_opt.h \ + /usr/include/bits/confname.h /usr/include/getopt.h \ + /usr/include/sys/time.h /usr/include/bits/time.h /usr/include/stdio.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/stdarg.h \ + /usr/include/libio.h /usr/include/_G_config.h \ + /usr/include/bits/stdio_lim.h include/Xserver/misc.h \ + include/X11/Xfuncproto.h include/X11/Xmd.h include/X11/X.h \ + include/Xserver/os.h include/X11/Xalloca.h include/X11/Xfuncs.h \ + include/Xserver/input.h include/Xserver/screenint.h \ + include/X11/Xproto.h include/X11/Xprotostr.h include/Xserver/window.h \ + include/Xserver/region.h include/Xserver/regionstr.h \ + include/Xserver/miscstruct.h include/Xserver/opaque.h \ + /usr/include/signal.h /usr/include/bits/signum.h \ + /usr/include/bits/siginfo.h /usr/include/bits/sigaction.h \ + /usr/include/bits/sigcontext.h /usr/include/asm/sigcontext.h \ + /usr/include/bits/sigstack.h /usr/include/sys/resource.h \ + /usr/include/bits/resource.h /usr/include/sys/stat.h \ + /usr/include/bits/stat.h /usr/include/ctype.h /usr/include/stdlib.h \ + /usr/include/alloca.h +stats.o: stats.c /usr/include/stdio.h /usr/include/features.h \ + /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/stddef.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/stdarg.h \ + /usr/include/bits/types.h /usr/include/libio.h \ + /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ + /usr/include/stdlib.h /usr/include/sys/types.h /usr/include/time.h \ + /usr/include/endian.h /usr/include/bits/endian.h \ + /usr/include/sys/select.h /usr/include/bits/select.h \ + /usr/include/bits/sigset.h /usr/include/sys/sysmacros.h \ + /usr/include/alloca.h rfb.h include/Xserver/scrnintstr.h \ + include/Xserver/screenint.h include/Xserver/misc.h \ + include/X11/Xosdefs.h include/X11/Xfuncproto.h include/X11/Xmd.h \ + include/X11/X.h include/Xserver/os.h include/X11/Xalloca.h \ + /usr/include/string.h include/X11/Xfuncs.h \ + include/Xserver/miscstruct.h include/X11/Xprotostr.h \ + include/Xserver/region.h include/Xserver/regionstr.h \ + include/Xserver/pixmap.h include/Xserver/gc.h include/X11/Xproto.h \ + include/Xserver/colormap.h include/Xserver/window.h \ + include/Xserver/cursor.h include/Xserver/validate.h \ + include/Xserver/dix.h include/Xserver/input.h rfbproto.h \ + libvncauth/vncauth.h /usr/include/netinet/in.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/limits.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/syslimits.h \ + /usr/include/limits.h /usr/include/bits/posix1_lim.h \ + /usr/include/bits/local_lim.h /usr/include/linux/limits.h \ + /usr/include/bits/posix2_lim.h /usr/include/stdint.h \ + /usr/include/bits/wordsize.h /usr/include/bits/socket.h \ + /usr/include/bits/sockaddr.h /usr/include/asm/socket.h \ + /usr/include/asm/sockios.h /usr/include/bits/in.h \ + /usr/include/bits/byteswap.h +corre.o: corre.c /usr/include/stdio.h /usr/include/features.h \ + /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/stddef.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/stdarg.h \ + /usr/include/bits/types.h /usr/include/libio.h \ + /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ + /usr/include/stdlib.h /usr/include/sys/types.h /usr/include/time.h \ + /usr/include/endian.h /usr/include/bits/endian.h \ + /usr/include/sys/select.h /usr/include/bits/select.h \ + /usr/include/bits/sigset.h /usr/include/sys/sysmacros.h \ + /usr/include/alloca.h rfb.h include/Xserver/scrnintstr.h \ + include/Xserver/screenint.h include/Xserver/misc.h \ + include/X11/Xosdefs.h include/X11/Xfuncproto.h include/X11/Xmd.h \ + include/X11/X.h include/Xserver/os.h include/X11/Xalloca.h \ + /usr/include/string.h include/X11/Xfuncs.h \ + include/Xserver/miscstruct.h include/X11/Xprotostr.h \ + include/Xserver/region.h include/Xserver/regionstr.h \ + include/Xserver/pixmap.h include/Xserver/gc.h include/X11/Xproto.h \ + include/Xserver/colormap.h include/Xserver/window.h \ + include/Xserver/cursor.h include/Xserver/validate.h \ + include/Xserver/dix.h include/Xserver/input.h rfbproto.h \ + libvncauth/vncauth.h /usr/include/netinet/in.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/limits.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/syslimits.h \ + /usr/include/limits.h /usr/include/bits/posix1_lim.h \ + /usr/include/bits/local_lim.h /usr/include/linux/limits.h \ + /usr/include/bits/posix2_lim.h /usr/include/stdint.h \ + /usr/include/bits/wordsize.h /usr/include/bits/socket.h \ + /usr/include/bits/sockaddr.h /usr/include/asm/socket.h \ + /usr/include/asm/sockios.h /usr/include/bits/in.h \ + /usr/include/bits/byteswap.h +hextile.o: hextile.c /usr/include/stdio.h /usr/include/features.h \ + /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/stddef.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/stdarg.h \ + /usr/include/bits/types.h /usr/include/libio.h \ + /usr/include/_G_config.h /usr/include/bits/stdio_lim.h rfb.h \ + include/Xserver/scrnintstr.h include/Xserver/screenint.h \ + include/Xserver/misc.h include/X11/Xosdefs.h include/X11/Xfuncproto.h \ + include/X11/Xmd.h include/X11/X.h include/Xserver/os.h \ + include/X11/Xalloca.h /usr/include/string.h include/X11/Xfuncs.h \ + include/Xserver/miscstruct.h include/X11/Xprotostr.h \ + include/Xserver/region.h include/Xserver/regionstr.h \ + include/Xserver/pixmap.h include/Xserver/gc.h include/X11/Xproto.h \ + include/Xserver/colormap.h include/Xserver/window.h \ + include/Xserver/cursor.h include/Xserver/validate.h \ + include/Xserver/dix.h include/Xserver/input.h rfbproto.h \ + libvncauth/vncauth.h /usr/include/netinet/in.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/limits.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/syslimits.h \ + /usr/include/limits.h /usr/include/bits/posix1_lim.h \ + /usr/include/bits/local_lim.h /usr/include/linux/limits.h \ + /usr/include/bits/posix2_lim.h /usr/include/stdint.h \ + /usr/include/bits/wordsize.h /usr/include/sys/types.h \ + /usr/include/time.h /usr/include/endian.h /usr/include/bits/endian.h \ + /usr/include/sys/select.h /usr/include/bits/select.h \ + /usr/include/bits/sigset.h /usr/include/sys/sysmacros.h \ + /usr/include/bits/socket.h /usr/include/bits/sockaddr.h \ + /usr/include/asm/socket.h /usr/include/asm/sockios.h \ + /usr/include/bits/in.h /usr/include/bits/byteswap.h +rre.o: rre.c /usr/include/stdio.h /usr/include/features.h \ + /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/stddef.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/stdarg.h \ + /usr/include/bits/types.h /usr/include/libio.h \ + /usr/include/_G_config.h /usr/include/bits/stdio_lim.h rfb.h \ + include/Xserver/scrnintstr.h include/Xserver/screenint.h \ + include/Xserver/misc.h include/X11/Xosdefs.h include/X11/Xfuncproto.h \ + include/X11/Xmd.h include/X11/X.h include/Xserver/os.h \ + include/X11/Xalloca.h /usr/include/string.h include/X11/Xfuncs.h \ + include/Xserver/miscstruct.h include/X11/Xprotostr.h \ + include/Xserver/region.h include/Xserver/regionstr.h \ + include/Xserver/pixmap.h include/Xserver/gc.h include/X11/Xproto.h \ + include/Xserver/colormap.h include/Xserver/window.h \ + include/Xserver/cursor.h include/Xserver/validate.h \ + include/Xserver/dix.h include/Xserver/input.h rfbproto.h \ + libvncauth/vncauth.h /usr/include/netinet/in.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/limits.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/syslimits.h \ + /usr/include/limits.h /usr/include/bits/posix1_lim.h \ + /usr/include/bits/local_lim.h /usr/include/linux/limits.h \ + /usr/include/bits/posix2_lim.h /usr/include/stdint.h \ + /usr/include/bits/wordsize.h /usr/include/sys/types.h \ + /usr/include/time.h /usr/include/endian.h /usr/include/bits/endian.h \ + /usr/include/sys/select.h /usr/include/bits/select.h \ + /usr/include/bits/sigset.h /usr/include/sys/sysmacros.h \ + /usr/include/bits/socket.h /usr/include/bits/sockaddr.h \ + /usr/include/asm/socket.h /usr/include/asm/sockios.h \ + /usr/include/bits/in.h /usr/include/bits/byteswap.h +translate.o: translate.c /usr/include/stdio.h /usr/include/features.h \ + /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/stddef.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/stdarg.h \ + /usr/include/bits/types.h /usr/include/libio.h \ + /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ + /usr/include/stdlib.h /usr/include/sys/types.h /usr/include/time.h \ + /usr/include/endian.h /usr/include/bits/endian.h \ + /usr/include/sys/select.h /usr/include/bits/select.h \ + /usr/include/bits/sigset.h /usr/include/sys/sysmacros.h \ + /usr/include/alloca.h rfb.h include/Xserver/scrnintstr.h \ + include/Xserver/screenint.h include/Xserver/misc.h \ + include/X11/Xosdefs.h include/X11/Xfuncproto.h include/X11/Xmd.h \ + include/X11/X.h include/Xserver/os.h include/X11/Xalloca.h \ + /usr/include/string.h include/X11/Xfuncs.h \ + include/Xserver/miscstruct.h include/X11/Xprotostr.h \ + include/Xserver/region.h include/Xserver/regionstr.h \ + include/Xserver/pixmap.h include/Xserver/gc.h include/X11/Xproto.h \ + include/Xserver/colormap.h include/Xserver/window.h \ + include/Xserver/cursor.h include/Xserver/validate.h \ + include/Xserver/dix.h include/Xserver/input.h rfbproto.h \ + libvncauth/vncauth.h /usr/include/netinet/in.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/limits.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/syslimits.h \ + /usr/include/limits.h /usr/include/bits/posix1_lim.h \ + /usr/include/bits/local_lim.h /usr/include/linux/limits.h \ + /usr/include/bits/posix2_lim.h /usr/include/stdint.h \ + /usr/include/bits/wordsize.h /usr/include/bits/socket.h \ + /usr/include/bits/sockaddr.h /usr/include/asm/socket.h \ + /usr/include/asm/sockios.h /usr/include/bits/in.h \ + /usr/include/bits/byteswap.h tableinittctemplate.c \ + tabletranstemplate.c +cutpaste.o: cutpaste.c /usr/include/stdio.h /usr/include/features.h \ + /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/stddef.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/stdarg.h \ + /usr/include/bits/types.h /usr/include/libio.h \ + /usr/include/_G_config.h /usr/include/bits/stdio_lim.h rfb.h \ + include/Xserver/scrnintstr.h include/Xserver/screenint.h \ + include/Xserver/misc.h include/X11/Xosdefs.h include/X11/Xfuncproto.h \ + include/X11/Xmd.h include/X11/X.h include/Xserver/os.h \ + include/X11/Xalloca.h /usr/include/string.h include/X11/Xfuncs.h \ + include/Xserver/miscstruct.h include/X11/Xprotostr.h \ + include/Xserver/region.h include/Xserver/regionstr.h \ + include/Xserver/pixmap.h include/Xserver/gc.h include/X11/Xproto.h \ + include/Xserver/colormap.h include/Xserver/window.h \ + include/Xserver/cursor.h include/Xserver/validate.h \ + include/Xserver/dix.h include/Xserver/input.h rfbproto.h \ + libvncauth/vncauth.h /usr/include/netinet/in.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/limits.h \ + /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/include/syslimits.h \ + /usr/include/limits.h /usr/include/bits/posix1_lim.h \ + /usr/include/bits/local_lim.h /usr/include/linux/limits.h \ + /usr/include/bits/posix2_lim.h /usr/include/stdint.h \ + /usr/include/bits/wordsize.h /usr/include/sys/types.h \ + /usr/include/time.h /usr/include/endian.h /usr/include/bits/endian.h \ + /usr/include/sys/select.h /usr/include/bits/select.h \ + /usr/include/bits/sigset.h /usr/include/sys/sysmacros.h \ + /usr/include/bits/socket.h /usr/include/bits/sockaddr.h \ + /usr/include/asm/socket.h /usr/include/asm/sockios.h \ + /usr/include/bits/in.h /usr/include/bits/byteswap.h diff --git a/.gdb_history b/.gdb_history new file mode 100755 index 0000000..128a356 --- /dev/null +++ b/.gdb_history @@ -0,0 +1,21 @@ +set args -desktop 'foobie bletch' +r +quit +where +info thread +info threads +thr 1 +where +quit +quit +r +where +info threads +thr 2 +where +f 31 +kill +r +r +r +quit diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..a3f6b12 --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5ef46f7 --- /dev/null +++ b/Makefile @@ -0,0 +1,63 @@ +CC=gcc +CFLAGS=-g -Wall +#CFLAGS=-O2 -Wall +RANLIB=ranlib + +INCLUDES=-I. -Ilibvncauth -Iinclude -Iinclude/X11 -Iinclude/Xserver +VNCAUTHLIB=-Llibvncauth -lvncauth +VNCSERVERLIB=-L. -lvncserver -lz -ljpeg + +# These two lines enable useage of PThreads +CFLAGS += -DHAVE_PTHREADS +VNCSERVERLIB += -lpthread + +LIBS=$(VNCSERVERLIB) $(VNCAUTHLIB) + +# for Mac OS X +OSX_LIBS = -framework ApplicationServices -framework Carbon + +# for Example +PTHREAD_LIBS = -lpthread + +SOURCES=main.c rfbserver.c miregion.c auth.c sockets.c xalloc.c \ + stats.c corre.c hextile.c rre.c translate.c cutpaste.c \ + zlib.c tight.c +OBJS=main.o rfbserver.o miregion.o auth.o sockets.o xalloc.o \ + stats.o corre.o hextile.o rre.o translate.o cutpaste.o \ + zlib.o tight.o + +all: example storepasswd + +install_OSX: OSXvnc-server + cp OSXvnc-server storepasswd ../OSXvnc/build/OSXvnc.app/Contents/MacOS + +.c.o: + $(CC) $(CFLAGS) $(INCLUDES) -c $< + +libvncserver.a: $(OBJS) + $(AR) cru $@ $(OBJS) + $(RANLIB) $@ + +example: example.o libvncauth/libvncauth.a libvncserver.a + $(CC) -o example example.o $(LIBS) $(PTHREAD_LIBS) + +OSXvnc-server: mac.o libvncauth/libvncauth.a libvncserver.a + $(CC) -o OSXvnc-server mac.o $(LIBS) $(OSX_LIBS) + +storepasswd: storepasswd.o libvncauth/libvncauth.a + $(CC) -o storepasswd storepasswd.o $(VNCAUTHLIB) + +libvncauth/libvncauth.a: + (cd libvncauth; make) + +clean: + rm -f $(OBJS) *~ core "#"* *.bak *.orig storepasswd.o *.a example.o \ + libvncauth/*.o libvncauth/*~ libvncauth/*.a + +realclean: clean + rm -f OSXvnc-server storepasswd + +depend: + $(CC) -M $(INCLUDES) $(SOURCES) >.depend + +#include .depend diff --git a/README b/README new file mode 100644 index 0000000..2c40beb --- /dev/null +++ b/README @@ -0,0 +1,19 @@ +OSXvnc: a VNC server for Mac OS X +Copyright (C) 2001 Dan McGuirk + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.dfdf + + +For help with OSXvnc, please visit http://www.osxvnc.com/. diff --git a/TODO b/TODO new file mode 100644 index 0000000..5ffaa28 --- /dev/null +++ b/TODO @@ -0,0 +1,17 @@ +.cutpaste + +httpd + +.other encodings + +adapt rdp2vnc (rdesktop) + +udp + +rfbCloseClient, rfbConnect, ConnectToTcpAddr + +CORBA + +translate.c: warning about non 8-bit colourmaps + +cursors diff --git a/auth.c b/auth.c new file mode 100644 index 0000000..3e23ada --- /dev/null +++ b/auth.c @@ -0,0 +1,141 @@ +/* + * auth.c - deal with authentication. + * + * This file implements the VNC authentication protocol when setting up an RFB + * connection. + */ + +/* + * OSXvnc Copyright (C) 2001 Dan McGuirk . + * Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge. + * All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include +#include +#include "rfb.h" + + +char *rfbAuthPasswdFile = NULL; + + +/* + * rfbAuthNewClient is called when we reach the point of authenticating + * a new client. If authentication isn't being used then we simply send + * rfbNoAuth. Otherwise we send rfbVncAuth plus the challenge. + */ + +void +rfbAuthNewClient(cl) + rfbClientPtr cl; +{ + char buf[4 + CHALLENGESIZE]; + int len; + + cl->state = RFB_AUTHENTICATION; + + if (rfbAuthPasswdFile && !cl->reverseConnection) { + + *(CARD32 *)buf = Swap32IfLE(rfbVncAuth); + vncRandomBytes(cl->authChallenge); + memcpy(&buf[4], (char *)cl->authChallenge, CHALLENGESIZE); + len = 4 + CHALLENGESIZE; + + } else { + + *(CARD32 *)buf = Swap32IfLE(rfbNoAuth); + len = 4; + cl->state = RFB_INITIALISATION; + } + + if (WriteExact(cl, buf, len) < 0) { + rfbLogPerror("rfbAuthNewClient: write"); + rfbCloseClient(cl); + return; + } +} + + +/* + * rfbAuthProcessClientMessage is called when the client sends its + * authentication response. + */ + +void +rfbAuthProcessClientMessage(cl) + rfbClientPtr cl; +{ + char *passwd; + int i, n; + CARD8 response[CHALLENGESIZE]; + CARD32 authResult; + + if ((n = ReadExact(cl, (char *)response, CHALLENGESIZE)) <= 0) { + if (n != 0) + rfbLogPerror("rfbAuthProcessClientMessage: read"); + rfbCloseClient(cl); + return; + } + + passwd = vncDecryptPasswdFromFile(rfbAuthPasswdFile); + + if (passwd == NULL) { + rfbLog("rfbAuthProcessClientMessage: could not get password from %s\n", + rfbAuthPasswdFile); + + authResult = Swap32IfLE(rfbVncAuthFailed); + + if (WriteExact(cl, (char *)&authResult, 4) < 0) { + rfbLogPerror("rfbAuthProcessClientMessage: write"); + } + rfbCloseClient(cl); + return; + } + + vncEncryptBytes(cl->authChallenge, passwd); + + /* Lose the password from memory */ + for (i = strlen(passwd); i >= 0; i--) { + passwd[i] = '\0'; + } + + free((char *)passwd); + + if (memcmp(cl->authChallenge, response, CHALLENGESIZE) != 0) { + rfbLog("rfbAuthProcessClientMessage: authentication failed from %s\n", + cl->host); + + authResult = Swap32IfLE(rfbVncAuthFailed); + + if (WriteExact(cl, (char *)&authResult, 4) < 0) { + rfbLogPerror("rfbAuthProcessClientMessage: write"); + } + rfbCloseClient(cl); + return; + } + + authResult = Swap32IfLE(rfbVncAuthOK); + + if (WriteExact(cl, (char *)&authResult, 4) < 0) { + rfbLogPerror("rfbAuthProcessClientMessage: write"); + rfbCloseClient(cl); + return; + } + + cl->state = RFB_INITIALISATION; +} diff --git a/corre.c b/corre.c new file mode 100644 index 0000000..5797efb --- /dev/null +++ b/corre.c @@ -0,0 +1,355 @@ +/* + * corre.c + * + * Routines to implement Compact Rise-and-Run-length Encoding (CoRRE). This + * code is based on krw's original javatel rfbserver. + */ + +/* + * OSXvnc Copyright (C) 2001 Dan McGuirk . + * Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge. + * All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include +#include +#include "rfb.h" + +/* + * rreBeforeBuf contains pixel data in the client's format. + * rreAfterBuf contains the RRE encoded version. If the RRE encoded version is + * larger than the raw data or if it exceeds rreAfterBufSize then + * raw encoding is used instead. + */ + +static int rreBeforeBufSize = 0; +static char *rreBeforeBuf = NULL; + +static int rreAfterBufSize = 0; +static char *rreAfterBuf = NULL; +static int rreAfterBufLen; + +static int subrectEncode8(CARD8 *data, int w, int h); +static int subrectEncode16(CARD16 *data, int w, int h); +static int subrectEncode32(CARD32 *data, int w, int h); +static CARD32 getBgColour(char *data, int size, int bpp); +static Bool rfbSendSmallRectEncodingCoRRE(rfbClientPtr cl, int x, int y, + int w, int h); + + +/* + * rfbSendRectEncodingCoRRE - send an arbitrary size rectangle using CoRRE + * encoding. + */ + +Bool +rfbSendRectEncodingCoRRE(cl, x, y, w, h) + rfbClientPtr cl; + int x, y, w, h; +{ + if (h > cl->correMaxHeight) { + rfbSendRectEncodingCoRRE(cl, x, y, w, cl->correMaxHeight ); + rfbSendRectEncodingCoRRE(cl, x, y + cl->correMaxHeight, w, + h - cl->correMaxHeight); + return FALSE; + } + + if (w > cl->correMaxWidth) { + rfbSendRectEncodingCoRRE(cl, x, y, cl->correMaxWidth, h); + rfbSendRectEncodingCoRRE(cl, x + cl->correMaxWidth, y, + w - cl->correMaxWidth, h); + return FALSE; + } + + rfbSendSmallRectEncodingCoRRE(cl, x, y, w, h); + return TRUE; +} + + + +/* + * rfbSendSmallRectEncodingCoRRE - send a small (guaranteed < 256x256) + * rectangle using CoRRE encoding. + */ + +static Bool +rfbSendSmallRectEncodingCoRRE(cl, x, y, w, h) + rfbClientPtr cl; + int x, y, w, h; +{ + rfbFramebufferUpdateRectHeader rect; + rfbRREHeader hdr; + int nSubrects; + int i; + char *fbptr = (cl->screen->frameBuffer + (cl->screen->paddedWidthInBytes * y) + + (x * (cl->screen->bitsPerPixel / 8))); + + int maxRawSize = (cl->screen->width * cl->screen->height + * (cl->format.bitsPerPixel / 8)); + + if (rreBeforeBufSize < maxRawSize) { + rreBeforeBufSize = maxRawSize; + if (rreBeforeBuf == NULL) + rreBeforeBuf = (char *)xalloc(rreBeforeBufSize); + else + rreBeforeBuf = (char *)xrealloc(rreBeforeBuf, rreBeforeBufSize); + } + + if (rreAfterBufSize < maxRawSize) { + rreAfterBufSize = maxRawSize; + if (rreAfterBuf == NULL) + rreAfterBuf = (char *)xalloc(rreAfterBufSize); + else + rreAfterBuf = (char *)xrealloc(rreAfterBuf, rreAfterBufSize); + } + + (*cl->translateFn)(cl->translateLookupTable,&(cl->screen->rfbServerFormat), + &cl->format, fbptr, rreBeforeBuf, + cl->screen->paddedWidthInBytes, w, h); + + switch (cl->format.bitsPerPixel) { + case 8: + nSubrects = subrectEncode8((CARD8 *)rreBeforeBuf, w, h); + break; + case 16: + nSubrects = subrectEncode16((CARD16 *)rreBeforeBuf, w, h); + break; + case 32: + nSubrects = subrectEncode32((CARD32 *)rreBeforeBuf, w, h); + break; + default: + rfbLog("getBgColour: bpp %d?\n",cl->format.bitsPerPixel); + exit(1); + } + + if (nSubrects < 0) { + + /* RRE encoding was too large, use raw */ + + return rfbSendRectEncodingRaw(cl, x, y, w, h); + } + + cl->rfbRectanglesSent[rfbEncodingCoRRE]++; + cl->rfbBytesSent[rfbEncodingCoRRE] += (sz_rfbFramebufferUpdateRectHeader + + sz_rfbRREHeader + rreAfterBufLen); + + if (cl->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader + > UPDATE_BUF_SIZE) + { + if (!rfbSendUpdateBuf(cl)) + return FALSE; + } + + rect.r.x = Swap16IfLE(x); + rect.r.y = Swap16IfLE(y); + rect.r.w = Swap16IfLE(w); + rect.r.h = Swap16IfLE(h); + rect.encoding = Swap32IfLE(rfbEncodingCoRRE); + + memcpy(&cl->updateBuf[cl->ublen], (char *)&rect, + sz_rfbFramebufferUpdateRectHeader); + cl->ublen += sz_rfbFramebufferUpdateRectHeader; + + hdr.nSubrects = Swap32IfLE(nSubrects); + + memcpy(&cl->updateBuf[cl->ublen], (char *)&hdr, sz_rfbRREHeader); + cl->ublen += sz_rfbRREHeader; + + for (i = 0; i < rreAfterBufLen;) { + + int bytesToCopy = UPDATE_BUF_SIZE - cl->ublen; + + if (i + bytesToCopy > rreAfterBufLen) { + bytesToCopy = rreAfterBufLen - i; + } + + memcpy(&cl->updateBuf[cl->ublen], &rreAfterBuf[i], bytesToCopy); + + cl->ublen += bytesToCopy; + i += bytesToCopy; + + if (cl->ublen == UPDATE_BUF_SIZE) { + if (!rfbSendUpdateBuf(cl)) + return FALSE; + } + } + + return TRUE; +} + + + +/* + * subrectEncode() encodes the given multicoloured rectangle as a background + * colour overwritten by single-coloured rectangles. It returns the number + * of subrectangles in the encoded buffer, or -1 if subrect encoding won't + * fit in the buffer. It puts the encoded rectangles in rreAfterBuf. The + * single-colour rectangle partition is not optimal, but does find the biggest + * horizontal or vertical rectangle top-left anchored to each consecutive + * coordinate position. + * + * The coding scheme is simply [...] where each + * is []. + */ + +#define DEFINE_SUBRECT_ENCODE(bpp) \ +static int \ +subrectEncode##bpp(data,w,h) \ + CARD##bpp *data; \ + int w; \ + int h; \ +{ \ + CARD##bpp cl; \ + rfbCoRRERectangle subrect; \ + int x,y; \ + int i,j; \ + int hx=0,hy,vx=0,vy; \ + int hyflag; \ + CARD##bpp *seg; \ + CARD##bpp *line; \ + int hw,hh,vw,vh; \ + int thex,they,thew,theh; \ + int numsubs = 0; \ + int newLen; \ + CARD##bpp bg = (CARD##bpp)getBgColour((char*)data,w*h,bpp); \ + \ + *((CARD##bpp*)rreAfterBuf) = bg; \ + \ + rreAfterBufLen = (bpp/8); \ + \ + for (y=0; y 0) && (i >= hx)) {hy += 1;} else {hyflag = 0;} \ + } \ + vy = j-1; \ + \ + /* We now have two possible subrects: (x,y,hx,hy) and (x,y,vx,vy) \ + * We'll choose the bigger of the two. \ + */ \ + hw = hx-x+1; \ + hh = hy-y+1; \ + vw = vx-x+1; \ + vh = vy-y+1; \ + \ + thex = x; \ + they = y; \ + \ + if ((hw*hh) > (vw*vh)) { \ + thew = hw; \ + theh = hh; \ + } else { \ + thew = vw; \ + theh = vh; \ + } \ + \ + subrect.x = thex; \ + subrect.y = they; \ + subrect.w = thew; \ + subrect.h = theh; \ + \ + newLen = rreAfterBufLen + (bpp/8) + sz_rfbCoRRERectangle; \ + if ((newLen > (w * h * (bpp/8))) || (newLen > rreAfterBufSize)) \ + return -1; \ + \ + numsubs += 1; \ + *((CARD##bpp*)(rreAfterBuf + rreAfterBufLen)) = cl; \ + rreAfterBufLen += (bpp/8); \ + memcpy(&rreAfterBuf[rreAfterBufLen],&subrect,sz_rfbCoRRERectangle); \ + rreAfterBufLen += sz_rfbCoRRERectangle; \ + \ + /* \ + * Now mark the subrect as done. \ + */ \ + for (j=they; j < (they+theh); j++) { \ + for (i=thex; i < (thex+thew); i++) { \ + data[j*w+i] = bg; \ + } \ + } \ + } \ + } \ + } \ + \ + return numsubs; \ +} + +DEFINE_SUBRECT_ENCODE(8) +DEFINE_SUBRECT_ENCODE(16) +DEFINE_SUBRECT_ENCODE(32) + + +/* + * getBgColour() gets the most prevalent colour in a byte array. + */ +static CARD32 +getBgColour(data,size,bpp) + char *data; + int size; + int bpp; +{ + +#define NUMCLRS 256 + + static int counts[NUMCLRS]; + int i,j,k; + + int maxcount = 0; + CARD8 maxclr = 0; + + if (bpp != 8) { + if (bpp == 16) { + return ((CARD16 *)data)[0]; + } else if (bpp == 32) { + return ((CARD32 *)data)[0]; + } else { + rfbLog("getBgColour: bpp %d?\n",bpp); + exit(1); + } + } + + for (i=0; i= NUMCLRS) { + rfbLog("getBgColour: unusual colour = %d\n", k); + exit(1); + } + counts[k] += 1; + if (counts[k] > maxcount) { + maxcount = counts[k]; + maxclr = ((CARD8 *)data)[j]; + } + } + + return maxclr; +} diff --git a/cutpaste.c b/cutpaste.c new file mode 100644 index 0000000..7dcefe7 --- /dev/null +++ b/cutpaste.c @@ -0,0 +1,39 @@ +/* + * cutpaste.c - routines to deal with cut & paste buffers / selection. + */ + +/* + * OSXvnc Copyright (C) 2001 Dan McGuirk . + * Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge. + * All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include +#include "rfb.h" + + +/* + * rfbSetXCutText sets the cut buffer to be the given string. We also clear + * the primary selection. Ideally we'd like to set it to the same thing, but I + * can't work out how to do that without some kind of helper X client. + */ + +void rfbGotXCutText(rfbScreenInfoPtr rfbScreen, char *str, int len) +{ + rfbSendServerCutText(rfbScreen, str, len); +} diff --git a/example.c b/example.c new file mode 100644 index 0000000..8d6a83e --- /dev/null +++ b/example.c @@ -0,0 +1,76 @@ +/* + * + * This is an example of how to use libvncserver. + * + * libvncserver example + * Copyright (C) 2001 Johannes E. Schindelin + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include +#include +#ifdef __IRIX__ +#include +#endif +#define XK_MISCELLANY +#include "rfb.h" +#include "keysymdef.h" + +const int maxx=640, maxy=480, bpp=4; + +void doptr(int buttonMask,int x,int y,rfbClientPtr cl) +{ + if(buttonMask && x>=0 && y>=0 && xscreen->frameBuffer[y*cl->screen->paddedWidthInBytes+x*bpp+i]^=0xff; + rfbMarkRectAsModified(cl->screen,x,y,x+1,y+1); + rfbGotXCutText(cl->screen,"Hallo",5); + } +} + +void dokey(Bool down,KeySym key,rfbClientPtr cl) +{ + if(down && key==XK_Escape) + rfbCloseClient(cl); +} + +int main(int argc,char** argv) +{ + int i,j; + rfbScreenInfoPtr rfbScreen = rfbDefaultScreenInit(argc,argv); + rfbScreen->desktopName="LibVNCServer Example"; + rfbScreen->frameBuffer = (char*)malloc(maxx*maxy*bpp); + rfbScreen->width=maxx; + rfbScreen->height=maxy; + rfbScreen->paddedWidthInBytes=maxx*bpp; + rfbScreen->ptrAddEvent=doptr; + rfbScreen->kbdAddEvent=dokey; + + for(i=0;iframeBuffer[(j*maxx+i)*bpp]=i*256/maxx; + rfbScreen->frameBuffer[(j*maxx+i)*bpp+1]=j*256/maxy; + rfbScreen->frameBuffer[(j*maxx+i)*bpp+2]=(i+j)*256/(maxx*maxy); + } + + runEventLoop(rfbScreen,40000,FALSE); + runEventLoop(rfbScreen,40000,TRUE); + while(1); + + return(0); +} diff --git a/go b/go new file mode 100644 index 0000000..4b75b26 --- /dev/null +++ b/go @@ -0,0 +1 @@ +´†L†`# \ No newline at end of file diff --git a/hextile.c b/hextile.c new file mode 100644 index 0000000..6166844 --- /dev/null +++ b/hextile.c @@ -0,0 +1,347 @@ +/* + * hextile.c + * + * Routines to implement Hextile Encoding + */ + +/* + * OSXvnc Copyright (C) 2001 Dan McGuirk . + * Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge. + * All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include +#include "rfb.h" + +static Bool sendHextiles8(rfbClientPtr cl, int x, int y, int w, int h); +static Bool sendHextiles16(rfbClientPtr cl, int x, int y, int w, int h); +static Bool sendHextiles32(rfbClientPtr cl, int x, int y, int w, int h); + + +/* + * rfbSendRectEncodingHextile - send a rectangle using hextile encoding. + */ + +Bool +rfbSendRectEncodingHextile(cl, x, y, w, h) + rfbClientPtr cl; + int x, y, w, h; +{ + rfbFramebufferUpdateRectHeader rect; + + if (cl->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE) { + if (!rfbSendUpdateBuf(cl)) + return FALSE; + } + + rect.r.x = Swap16IfLE(x); + rect.r.y = Swap16IfLE(y); + rect.r.w = Swap16IfLE(w); + rect.r.h = Swap16IfLE(h); + rect.encoding = Swap32IfLE(rfbEncodingHextile); + + memcpy(&cl->updateBuf[cl->ublen], (char *)&rect, + sz_rfbFramebufferUpdateRectHeader); + cl->ublen += sz_rfbFramebufferUpdateRectHeader; + + cl->rfbRectanglesSent[rfbEncodingHextile]++; + cl->rfbBytesSent[rfbEncodingHextile] += sz_rfbFramebufferUpdateRectHeader; + + switch (cl->format.bitsPerPixel) { + case 8: + return sendHextiles8(cl, x, y, w, h); + case 16: + return sendHextiles16(cl, x, y, w, h); + case 32: + return sendHextiles32(cl, x, y, w, h); + } + + rfbLog("rfbSendRectEncodingHextile: bpp %d?\n", cl->format.bitsPerPixel); + return FALSE; +} + + +#define PUT_PIXEL8(pix) (cl->updateBuf[cl->ublen++] = (pix)) + +#define PUT_PIXEL16(pix) (cl->updateBuf[cl->ublen++] = ((char*)&(pix))[0], \ + cl->updateBuf[cl->ublen++] = ((char*)&(pix))[1]) + +#define PUT_PIXEL32(pix) (cl->updateBuf[cl->ublen++] = ((char*)&(pix))[0], \ + cl->updateBuf[cl->ublen++] = ((char*)&(pix))[1], \ + cl->updateBuf[cl->ublen++] = ((char*)&(pix))[2], \ + cl->updateBuf[cl->ublen++] = ((char*)&(pix))[3]) + + +#define DEFINE_SEND_HEXTILES(bpp) \ + \ + \ +static Bool subrectEncode##bpp(rfbClientPtr cli, CARD##bpp *data, int w, int h, \ + CARD##bpp bg, CARD##bpp fg, Bool mono); \ +static void testColours##bpp(CARD##bpp *data, int size, Bool *mono, \ + Bool *solid, CARD##bpp *bg, CARD##bpp *fg); \ + \ + \ +/* \ + * rfbSendHextiles \ + */ \ + \ +static Bool \ +sendHextiles##bpp(cl, rx, ry, rw, rh) \ + rfbClientPtr cl; \ + int rx, ry, rw, rh; \ +{ \ + int x, y, w, h; \ + int startUblen; \ + char *fbptr; \ + CARD##bpp bg = 0, fg = 0, newBg, newFg; \ + Bool mono, solid; \ + Bool validBg = FALSE; \ + Bool validFg = FALSE; \ + CARD##bpp clientPixelData[16*16*(bpp/8)]; \ + \ + for (y = ry; y < ry+rh; y += 16) { \ + for (x = rx; x < rx+rw; x += 16) { \ + w = h = 16; \ + if (rx+rw - x < 16) \ + w = rx+rw - x; \ + if (ry+rh - y < 16) \ + h = ry+rh - y; \ + \ + if ((cl->ublen + 1 + (2 + 16 * 16) * (bpp/8)) > \ + UPDATE_BUF_SIZE) { \ + if (!rfbSendUpdateBuf(cl)) \ + return FALSE; \ + } \ + \ + fbptr = (cl->screen->frameBuffer + (cl->screen->paddedWidthInBytes * y) \ + + (x * (cl->screen->bitsPerPixel / 8))); \ + \ + (*cl->translateFn)(cl->translateLookupTable, &(cl->screen->rfbServerFormat), \ + &cl->format, fbptr, (char *)clientPixelData, \ + cl->screen->paddedWidthInBytes, w, h); \ + \ + startUblen = cl->ublen; \ + cl->updateBuf[startUblen] = 0; \ + cl->ublen++; \ + \ + testColours##bpp(clientPixelData, w * h, \ + &mono, &solid, &newBg, &newFg); \ + \ + if (!validBg || (newBg != bg)) { \ + validBg = TRUE; \ + bg = newBg; \ + cl->updateBuf[startUblen] |= rfbHextileBackgroundSpecified; \ + PUT_PIXEL##bpp(bg); \ + } \ + \ + if (solid) { \ + cl->rfbBytesSent[rfbEncodingHextile] += cl->ublen - startUblen; \ + continue; \ + } \ + \ + cl->updateBuf[startUblen] |= rfbHextileAnySubrects; \ + \ + if (mono) { \ + if (!validFg || (newFg != fg)) { \ + validFg = TRUE; \ + fg = newFg; \ + cl->updateBuf[startUblen] |= rfbHextileForegroundSpecified; \ + PUT_PIXEL##bpp(fg); \ + } \ + } else { \ + validFg = FALSE; \ + cl->updateBuf[startUblen] |= rfbHextileSubrectsColoured; \ + } \ + \ + if (!subrectEncode##bpp(cl, clientPixelData, w, h, bg, fg, mono)) { \ + /* encoding was too large, use raw */ \ + validBg = FALSE; \ + validFg = FALSE; \ + cl->ublen = startUblen; \ + cl->updateBuf[cl->ublen++] = rfbHextileRaw; \ + (*cl->translateFn)(cl->translateLookupTable, \ + &(cl->screen->rfbServerFormat), &cl->format, fbptr, \ + (char *)clientPixelData, \ + cl->screen->paddedWidthInBytes, w, h); \ + \ + memcpy(&cl->updateBuf[cl->ublen], (char *)clientPixelData, \ + w * h * (bpp/8)); \ + \ + cl->ublen += w * h * (bpp/8); \ + } \ + \ + cl->rfbBytesSent[rfbEncodingHextile] += cl->ublen - startUblen; \ + } \ + } \ + \ + return TRUE; \ +} \ + \ + \ +static Bool \ +subrectEncode##bpp(rfbClientPtr cl, CARD##bpp *data, int w, int h, \ + CARD##bpp bg, CARD##bpp fg, Bool mono) \ +{ \ + CARD##bpp cl2; \ + int x,y; \ + int i,j; \ + int hx=0,hy,vx=0,vy; \ + int hyflag; \ + CARD##bpp *seg; \ + CARD##bpp *line; \ + int hw,hh,vw,vh; \ + int thex,they,thew,theh; \ + int numsubs = 0; \ + int newLen; \ + int nSubrectsUblen; \ + \ + nSubrectsUblen = cl->ublen; \ + cl->ublen++; \ + \ + for (y=0; y 0) && (i >= hx)) { \ + hy += 1; \ + } else { \ + hyflag = 0; \ + } \ + } \ + vy = j-1; \ + \ + /* We now have two possible subrects: (x,y,hx,hy) and \ + * (x,y,vx,vy). We'll choose the bigger of the two. \ + */ \ + hw = hx-x+1; \ + hh = hy-y+1; \ + vw = vx-x+1; \ + vh = vy-y+1; \ + \ + thex = x; \ + they = y; \ + \ + if ((hw*hh) > (vw*vh)) { \ + thew = hw; \ + theh = hh; \ + } else { \ + thew = vw; \ + theh = vh; \ + } \ + \ + if (mono) { \ + newLen = cl->ublen - nSubrectsUblen + 2; \ + } else { \ + newLen = cl->ublen - nSubrectsUblen + bpp/8 + 2; \ + } \ + \ + if (newLen > (w * h * (bpp/8))) \ + return FALSE; \ + \ + numsubs += 1; \ + \ + if (!mono) PUT_PIXEL##bpp(cl2); \ + \ + cl->updateBuf[cl->ublen++] = rfbHextilePackXY(thex,they); \ + cl->updateBuf[cl->ublen++] = rfbHextilePackWH(thew,theh); \ + \ + /* \ + * Now mark the subrect as done. \ + */ \ + for (j=they; j < (they+theh); j++) { \ + for (i=thex; i < (thex+thew); i++) { \ + data[j*w+i] = bg; \ + } \ + } \ + } \ + } \ + } \ + \ + cl->updateBuf[nSubrectsUblen] = numsubs; \ + \ + return TRUE; \ +} \ + \ + \ +/* \ + * testColours() tests if there are one (solid), two (mono) or more \ + * colours in a tile and gets a reasonable guess at the best background \ + * pixel, and the foreground pixel for mono. \ + */ \ + \ +static void \ +testColours##bpp(data,size,mono,solid,bg,fg) \ + CARD##bpp *data; \ + int size; \ + Bool *mono; \ + Bool *solid; \ + CARD##bpp *bg; \ + CARD##bpp *fg; \ +{ \ + CARD##bpp colour1 = 0, colour2 = 0; \ + int n1 = 0, n2 = 0; \ + *mono = TRUE; \ + *solid = TRUE; \ + \ + for (; size > 0; size--, data++) { \ + \ + if (n1 == 0) \ + colour1 = *data; \ + \ + if (*data == colour1) { \ + n1++; \ + continue; \ + } \ + \ + if (n2 == 0) { \ + *solid = FALSE; \ + colour2 = *data; \ + } \ + \ + if (*data == colour2) { \ + n2++; \ + continue; \ + } \ + \ + *mono = FALSE; \ + break; \ + } \ + \ + if (n1 > n2) { \ + *bg = colour1; \ + *fg = colour2; \ + } else { \ + *bg = colour2; \ + *fg = colour1; \ + } \ +} + +DEFINE_SEND_HEXTILES(8) +DEFINE_SEND_HEXTILES(16) +DEFINE_SEND_HEXTILES(32) diff --git a/include/X11/X.h b/include/X11/X.h new file mode 100755 index 0000000..95fa6cb --- /dev/null +++ b/include/X11/X.h @@ -0,0 +1,693 @@ +/* + * $XConsortium: X.h,v 1.69 94/04/17 20:10:48 dpw Exp $ + */ + +/* Definitions for the X window system likely to be used by applications */ + +#ifndef X_H +#define X_H + +/*********************************************************** + +Copyright (c) 1987 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. + + +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. + +******************************************************************/ +#define X_PROTOCOL 11 /* current protocol version */ +#define X_PROTOCOL_REVISION 0 /* current minor version */ + +/* Resources */ + +/* + * _XSERVER64 must ONLY be defined when compiling X server sources on + * systems where unsigned long is not 32 bits, must NOT be used in + * client or library code. + */ +#ifndef _XSERVER64 +typedef unsigned long XID; +typedef unsigned long Mask; +typedef unsigned long Atom; +typedef unsigned long VisualID; +typedef unsigned long Time; +#else +#include +typedef CARD32 XID; +typedef CARD32 Mask; +typedef CARD32 Atom; +typedef CARD32 VisualID; +typedef CARD32 Time; +#endif + +typedef XID Window; +typedef XID Drawable; +typedef XID Font; +typedef XID Pixmap; +typedef XID X11Cursor; /* conflict with CoreGraphics */ +typedef XID Colormap; +typedef XID GContext; +typedef XID KeySym; + +typedef unsigned char KeyCode; + +/***************************************************************** + * RESERVED RESOURCE AND CONSTANT DEFINITIONS + *****************************************************************/ + +#define None 0L /* universal null resource or null atom */ + +#define ParentRelative 1L /* background pixmap in CreateWindow + and ChangeWindowAttributes */ + +#define CopyFromParent 0L /* border pixmap in CreateWindow + and ChangeWindowAttributes + special VisualID and special window + class passed to CreateWindow */ + +#define PointerWindow 0L /* destination window in SendEvent */ +#define InputFocus 1L /* destination window in SendEvent */ + +#define PointerRoot 1L /* focus window in SetInputFocus */ + +#define AnyPropertyType 0L /* special Atom, passed to GetProperty */ + +#define AnyKey 0L /* special Key Code, passed to GrabKey */ + +#define AnyButton 0L /* special Button Code, passed to GrabButton */ + +#define AllTemporary 0L /* special Resource ID passed to KillClient */ + +#define CurrentTime 0L /* special Time */ + +#define NoSymbol 0L /* special KeySym */ + +/***************************************************************** + * EVENT DEFINITIONS + *****************************************************************/ + +/* Input Event Masks. Used as event-mask window attribute and as arguments + to Grab requests. Not to be confused with event names. */ + +#define NoEventMask 0L +#define KeyPressMask (1L<<0) +#define KeyReleaseMask (1L<<1) +#define ButtonPressMask (1L<<2) +#define ButtonReleaseMask (1L<<3) +#define EnterWindowMask (1L<<4) +#define LeaveWindowMask (1L<<5) +#define PointerMotionMask (1L<<6) +#define PointerMotionHintMask (1L<<7) +#define Button1MotionMask (1L<<8) +#define Button2MotionMask (1L<<9) +#define Button3MotionMask (1L<<10) +#define Button4MotionMask (1L<<11) +#define Button5MotionMask (1L<<12) +#define ButtonMotionMask (1L<<13) +#define KeymapStateMask (1L<<14) +#define ExposureMask (1L<<15) +#define VisibilityChangeMask (1L<<16) +#define StructureNotifyMask (1L<<17) +#define ResizeRedirectMask (1L<<18) +#define SubstructureNotifyMask (1L<<19) +#define SubstructureRedirectMask (1L<<20) +#define FocusChangeMask (1L<<21) +#define PropertyChangeMask (1L<<22) +#define ColormapChangeMask (1L<<23) +#define OwnerGrabButtonMask (1L<<24) + +/* Event names. Used in "type" field in XEvent structures. Not to be +confused with event masks above. They start from 2 because 0 and 1 +are reserved in the protocol for errors and replies. */ + +#define KeyPress 2 +#define KeyRelease 3 +#define ButtonPress 4 +#define ButtonRelease 5 +#define MotionNotify 6 +#define EnterNotify 7 +#define LeaveNotify 8 +#define FocusIn 9 +#define FocusOut 10 +#define KeymapNotify 11 +#define Expose 12 +#define GraphicsExpose 13 +#define NoExpose 14 +#define VisibilityNotify 15 +#define CreateNotify 16 +#define DestroyNotify 17 +#define UnmapNotify 18 +#define MapNotify 19 +#define MapRequest 20 +#define ReparentNotify 21 +#define ConfigureNotify 22 +#define ConfigureRequest 23 +#define GravityNotify 24 +#define ResizeRequest 25 +#define CirculateNotify 26 +#define CirculateRequest 27 +#define PropertyNotify 28 +#define SelectionClear 29 +#define SelectionRequest 30 +#define SelectionNotify 31 +#define ColormapNotify 32 +#define ClientMessage 33 +#define MappingNotify 34 +#define LASTEvent 35 /* must be bigger than any event # */ + + +/* Key masks. Used as modifiers to GrabButton and GrabKey, results of QueryPointer, + state in various key-, mouse-, and button-related events. */ + +#define ShiftMask (1<<0) +#define LockMask (1<<1) +#define ControlMask (1<<2) +#define Mod1Mask (1<<3) +#define Mod2Mask (1<<4) +#define Mod3Mask (1<<5) +#define Mod4Mask (1<<6) +#define Mod5Mask (1<<7) + +/* modifier names. Used to build a SetModifierMapping request or + to read a GetModifierMapping request. These correspond to the + masks defined above. */ +#define ShiftMapIndex 0 +#define LockMapIndex 1 +#define ControlMapIndex 2 +#define Mod1MapIndex 3 +#define Mod2MapIndex 4 +#define Mod3MapIndex 5 +#define Mod4MapIndex 6 +#define Mod5MapIndex 7 + + +/* button masks. Used in same manner as Key masks above. Not to be confused + with button names below. */ + +#define Button1Mask (1<<8) +#define Button2Mask (1<<9) +#define Button3Mask (1<<10) +#define Button4Mask (1<<11) +#define Button5Mask (1<<12) + +#define AnyModifier (1<<15) /* used in GrabButton, GrabKey */ + + +/* button names. Used as arguments to GrabButton and as detail in ButtonPress + and ButtonRelease events. Not to be confused with button masks above. + Note that 0 is already defined above as "AnyButton". */ + +#define Button1 1 +#define Button2 2 +#define Button3 3 +#define Button4 4 +#define Button5 5 + +/* Notify modes */ + +#define NotifyNormal 0 +#define NotifyGrab 1 +#define NotifyUngrab 2 +#define NotifyWhileGrabbed 3 + +#define NotifyHint 1 /* for MotionNotify events */ + +/* Notify detail */ + +#define NotifyAncestor 0 +#define NotifyVirtual 1 +#define NotifyInferior 2 +#define NotifyNonlinear 3 +#define NotifyNonlinearVirtual 4 +#define NotifyPointer 5 +#define NotifyPointerRoot 6 +#define NotifyDetailNone 7 + +/* Visibility notify */ + +#define VisibilityUnobscured 0 +#define VisibilityPartiallyObscured 1 +#define VisibilityFullyObscured 2 + +/* Circulation request */ + +#define PlaceOnTop 0 +#define PlaceOnBottom 1 + +/* protocol families */ + +#define FamilyInternet 0 +#define FamilyDECnet 1 +#define FamilyChaos 2 + +/* Property notification */ + +#define PropertyNewValue 0 +#define PropertyDelete 1 + +/* Color Map notification */ + +#define ColormapUninstalled 0 +#define ColormapInstalled 1 + +/* GrabPointer, GrabButton, GrabKeyboard, GrabKey Modes */ + +#define GrabModeSync 0 +#define GrabModeAsync 1 + +/* GrabPointer, GrabKeyboard reply status */ + +#define GrabSuccess 0 +#define AlreadyGrabbed 1 +#define GrabInvalidTime 2 +#define GrabNotViewable 3 +#define GrabFrozen 4 + +/* AllowEvents modes */ + +#define AsyncPointer 0 +#define SyncPointer 1 +#define ReplayPointer 2 +#define AsyncKeyboard 3 +#define SyncKeyboard 4 +#define ReplayKeyboard 5 +#define AsyncBoth 6 +#define SyncBoth 7 + +/* Used in SetInputFocus, GetInputFocus */ + +#define RevertToNone (int)None +#define RevertToPointerRoot (int)PointerRoot +#define RevertToParent 2 + +/***************************************************************** + * ERROR CODES + *****************************************************************/ + +#define Success 0 /* everything's okay */ +#define BadRequest 1 /* bad request code */ +#define BadValue 2 /* int parameter out of range */ +#define BadWindow 3 /* parameter not a Window */ +#define BadPixmap 4 /* parameter not a Pixmap */ +#define BadAtom 5 /* parameter not an Atom */ +#define BadCursor 6 /* parameter not a Cursor */ +#define BadFont 7 /* parameter not a Font */ +#define BadMatch 8 /* parameter mismatch */ +#define BadDrawable 9 /* parameter not a Pixmap or Window */ +#define BadAccess 10 /* depending on context: + - key/button already grabbed + - attempt to free an illegal + cmap entry + - attempt to store into a read-only + color map entry. + - attempt to modify the access control + list from other than the local host. + */ +#define BadAlloc 11 /* insufficient resources */ +#define BadColor 12 /* no such colormap */ +#define BadGC 13 /* parameter not a GC */ +#define BadIDChoice 14 /* choice not in range or already used */ +#define BadName 15 /* font or color name doesn't exist */ +#define BadLength 16 /* Request length incorrect */ +#define BadImplementation 17 /* server is defective */ + +#define FirstExtensionError 128 +#define LastExtensionError 255 + +/***************************************************************** + * WINDOW DEFINITIONS + *****************************************************************/ + +/* Window classes used by CreateWindow */ +/* Note that CopyFromParent is already defined as 0 above */ + +#define InputOutput 1 +#define InputOnly 2 + +/* Window attributes for CreateWindow and ChangeWindowAttributes */ + +#define CWBackPixmap (1L<<0) +#define CWBackPixel (1L<<1) +#define CWBorderPixmap (1L<<2) +#define CWBorderPixel (1L<<3) +#define CWBitGravity (1L<<4) +#define CWWinGravity (1L<<5) +#define CWBackingStore (1L<<6) +#define CWBackingPlanes (1L<<7) +#define CWBackingPixel (1L<<8) +#define CWOverrideRedirect (1L<<9) +#define CWSaveUnder (1L<<10) +#define CWEventMask (1L<<11) +#define CWDontPropagate (1L<<12) +#define CWColormap (1L<<13) +#define CWCursor (1L<<14) + +/* ConfigureWindow structure */ + +#define CWX (1<<0) +#define CWY (1<<1) +#define CWWidth (1<<2) +#define CWHeight (1<<3) +#define CWBorderWidth (1<<4) +#define CWSibling (1<<5) +#define CWStackMode (1<<6) + + +/* Bit Gravity */ + +#define ForgetGravity 0 +#define NorthWestGravity 1 +#define NorthGravity 2 +#define NorthEastGravity 3 +#define WestGravity 4 +#define CenterGravity 5 +#define EastGravity 6 +#define SouthWestGravity 7 +#define SouthGravity 8 +#define SouthEastGravity 9 +#define StaticGravity 10 + +/* Window gravity + bit gravity above */ + +#define UnmapGravity 0 + +/* Used in CreateWindow for backing-store hint */ + +#define NotUseful 0 +#define WhenMapped 1 +#define Always 2 + +/* Used in GetWindowAttributes reply */ + +#define IsUnmapped 0 +#define IsUnviewable 1 +#define IsViewable 2 + +/* Used in ChangeSaveSet */ + +#define SetModeInsert 0 +#define SetModeDelete 1 + +/* Used in ChangeCloseDownMode */ + +#define DestroyAll 0 +#define RetainPermanent 1 +#define RetainTemporary 2 + +/* Window stacking method (in configureWindow) */ + +#define Above 0 +#define Below 1 +#define TopIf 2 +#define BottomIf 3 +#define Opposite 4 + +/* Circulation direction */ + +#define RaiseLowest 0 +#define LowerHighest 1 + +/* Property modes */ + +#define PropModeReplace 0 +#define PropModePrepend 1 +#define PropModeAppend 2 + +/***************************************************************** + * GRAPHICS DEFINITIONS + *****************************************************************/ + +/* graphics functions, as in GC.alu */ + +#define GXclear 0x0 /* 0 */ +#define GXand 0x1 /* src AND dst */ +#define GXandReverse 0x2 /* src AND NOT dst */ +#define GXcopy 0x3 /* src */ +#define GXandInverted 0x4 /* NOT src AND dst */ +#define GXnoop 0x5 /* dst */ +#define GXxor 0x6 /* src XOR dst */ +#define GXor 0x7 /* src OR dst */ +#define GXnor 0x8 /* NOT src AND NOT dst */ +#define GXequiv 0x9 /* NOT src XOR dst */ +#define GXinvert 0xa /* NOT dst */ +#define GXorReverse 0xb /* src OR NOT dst */ +#define GXcopyInverted 0xc /* NOT src */ +#define GXorInverted 0xd /* NOT src OR dst */ +#define GXnand 0xe /* NOT src OR NOT dst */ +#define GXset 0xf /* 1 */ + +/* LineStyle */ + +#define LineSolid 0 +#define LineOnOffDash 1 +#define LineDoubleDash 2 + +/* capStyle */ + +#define CapNotLast 0 +#define CapButt 1 +#define CapRound 2 +#define CapProjecting 3 + +/* joinStyle */ + +#define JoinMiter 0 +#define JoinRound 1 +#define JoinBevel 2 + +/* fillStyle */ + +#define FillSolid 0 +#define FillTiled 1 +#define FillStippled 2 +#define FillOpaqueStippled 3 + +/* fillRule */ + +#define EvenOddRule 0 +#define WindingRule 1 + +/* subwindow mode */ + +#define ClipByChildren 0 +#define IncludeInferiors 1 + +/* SetClipRectangles ordering */ + +#define Unsorted 0 +#define YSorted 1 +#define YXSorted 2 +#define YXBanded 3 + +/* CoordinateMode for drawing routines */ + +#define CoordModeOrigin 0 /* relative to the origin */ +#define CoordModePrevious 1 /* relative to previous point */ + +/* Polygon shapes */ + +#define Complex 0 /* paths may intersect */ +#define Nonconvex 1 /* no paths intersect, but not convex */ +#define Convex 2 /* wholly convex */ + +/* Arc modes for PolyFillArc */ + +#define ArcChord 0 /* join endpoints of arc */ +#define ArcPieSlice 1 /* join endpoints to center of arc */ + +/* GC components: masks used in CreateGC, CopyGC, ChangeGC, OR'ed into + GC.stateChanges */ + +#define GCFunction (1L<<0) +#define GCPlaneMask (1L<<1) +#define GCForeground (1L<<2) +#define GCBackground (1L<<3) +#define GCLineWidth (1L<<4) +#define GCLineStyle (1L<<5) +#define GCCapStyle (1L<<6) +#define GCJoinStyle (1L<<7) +#define GCFillStyle (1L<<8) +#define GCFillRule (1L<<9) +#define GCTile (1L<<10) +#define GCStipple (1L<<11) +#define GCTileStipXOrigin (1L<<12) +#define GCTileStipYOrigin (1L<<13) +#define GCFont (1L<<14) +#define GCSubwindowMode (1L<<15) +#define GCGraphicsExposures (1L<<16) +#define GCClipXOrigin (1L<<17) +#define GCClipYOrigin (1L<<18) +#define GCClipMask (1L<<19) +#define GCDashOffset (1L<<20) +#define GCDashList (1L<<21) +#define GCArcMode (1L<<22) + +#define GCLastBit 22 +/***************************************************************** + * FONTS + *****************************************************************/ + +/* used in QueryFont -- draw direction */ + +#define FontLeftToRight 0 +#define FontRightToLeft 1 + +#define FontChange 255 + +/***************************************************************** + * IMAGING + *****************************************************************/ + +/* ImageFormat -- PutImage, GetImage */ + +#define XYBitmap 0 /* depth 1, XYFormat */ +#define XYPixmap 1 /* depth == drawable depth */ +#define ZPixmap 2 /* depth == drawable depth */ + +/***************************************************************** + * COLOR MAP STUFF + *****************************************************************/ + +/* For CreateColormap */ + +#define AllocNone 0 /* create map with no entries */ +#define AllocAll 1 /* allocate entire map writeable */ + + +/* Flags used in StoreNamedColor, StoreColors */ + +#define DoRed (1<<0) +#define DoGreen (1<<1) +#define DoBlue (1<<2) + +/***************************************************************** + * CURSOR STUFF + *****************************************************************/ + +/* QueryBestSize Class */ + +#define CursorShape 0 /* largest size that can be displayed */ +#define TileShape 1 /* size tiled fastest */ +#define StippleShape 2 /* size stippled fastest */ + +/***************************************************************** + * KEYBOARD/POINTER STUFF + *****************************************************************/ + +#define AutoRepeatModeOff 0 +#define AutoRepeatModeOn 1 +#define AutoRepeatModeDefault 2 + +#define LedModeOff 0 +#define LedModeOn 1 + +/* masks for ChangeKeyboardControl */ + +#define KBKeyClickPercent (1L<<0) +#define KBBellPercent (1L<<1) +#define KBBellPitch (1L<<2) +#define KBBellDuration (1L<<3) +#define KBLed (1L<<4) +#define KBLedMode (1L<<5) +#define KBKey (1L<<6) +#define KBAutoRepeatMode (1L<<7) + +#define MappingSuccess 0 +#define MappingBusy 1 +#define MappingFailed 2 + +#define MappingModifier 0 +#define MappingKeyboard 1 +#define MappingPointer 2 + +/***************************************************************** + * SCREEN SAVER STUFF + *****************************************************************/ + +#define DontPreferBlanking 0 +#define PreferBlanking 1 +#define DefaultBlanking 2 + +#define DisableScreenSaver 0 +#define DisableScreenInterval 0 + +#define DontAllowExposures 0 +#define AllowExposures 1 +#define DefaultExposures 2 + +/* for ForceScreenSaver */ + +#define ScreenSaverReset 0 +#define ScreenSaverActive 1 + +/***************************************************************** + * HOSTS AND CONNECTIONS + *****************************************************************/ + +/* for ChangeHosts */ + +#define HostInsert 0 +#define HostDelete 1 + +/* for ChangeAccessControl */ + +#define EnableAccess 1 +#define DisableAccess 0 + +/* Display classes used in opening the connection + * Note that the statically allocated ones are even numbered and the + * dynamically changeable ones are odd numbered */ + +#define StaticGray 0 +#define GrayScale 1 +#define StaticColor 2 +#define PseudoColor 3 +#define TrueColor 4 +#define DirectColor 5 + + +/* Byte order used in imageByteOrder and bitmapBitOrder */ + +#define LSBFirst 0 +#define MSBFirst 1 + +#endif /* X_H */ diff --git a/include/X11/Xalloca.h b/include/X11/Xalloca.h new file mode 100755 index 0000000..a730603 --- /dev/null +++ b/include/X11/Xalloca.h @@ -0,0 +1,137 @@ +/* $XConsortium: Xalloca.h /main/6 1996/09/28 16:17:22 rws $ */ + +/* + +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. + +*/ + +/* + * The purpose of this header is to define the macros ALLOCATE_LOCAL and + * DEALLOCATE_LOCAL appropriately for the platform being compiled on. + * These macros are used to make fast, function-local memory allocations. + * Their characteristics are as follows: + * + * void *ALLOCATE_LOCAL(int size) + * Returns a pointer to size bytes of memory, or NULL if the allocation + * failed. The memory must be freed with DEALLOCATE_LOCAL before the + * function that made the allocation returns. You should not ask for + * large blocks of memory with this function, since on many platforms + * the memory comes from the stack, which may have limited size. + * + * void DEALLOCATE_LOCAL(void *) + * Frees the memory allocated by ALLOCATE_LOCAL. Omission of this + * step may be harmless on some platforms, but will result in + * memory leaks or worse on others. + * + * Before including this file, you should define two macros, + * ALLOCATE_LOCAL_FALLBACK and DEALLOCATE_LOCAL_FALLBACK, that have the + * same characteristics as ALLOCATE_LOCAL and DEALLOCATE_LOCAL. The + * header uses the fallbacks if it doesn't know a "better" way to define + * ALLOCATE_LOCAL and DEALLOCATE_LOCAL. Typical usage would be: + * + * #define ALLOCATE_LOCAL_FALLBACK(_size) malloc(_size) + * #define DEALLOCATE_LOCAL_FALLBACK(_ptr) free(_ptr) + * #include "Xalloca.h" + */ + +#ifndef XALLOCA_H +#define XALLOCA_H 1 + +#ifdef INCLUDE_ALLOCA_H +# include +#endif + +#ifndef NO_ALLOCA +/* + * os-dependent definition of local allocation and deallocation + * If you want something other than (DE)ALLOCATE_LOCAL_FALLBACK + * for ALLOCATE/DEALLOCATE_LOCAL then you add that in here. + */ +# if defined(__HIGHC__) +# ifndef NCR + extern char *alloca(); +# if HCVERSION < 21003 +# define ALLOCATE_LOCAL(size) alloca((int)(size)) + pragma on(alloca); +# else /* HCVERSION >= 21003 */ +# define ALLOCATE_LOCAL(size) _Alloca((int)(size)) +# endif /* HCVERSION < 21003 */ +# else /* NCR */ +# define ALLOCATE_LOCAL(size) alloca(size) +# endif +# define DEALLOCATE_LOCAL(ptr) /* as nothing */ +# endif /* defined(__HIGHC__) */ + + +# ifdef __GNUC__ +# ifndef alloca +# define alloca __builtin_alloca +# endif /* !alloca */ +# define ALLOCATE_LOCAL(size) alloca((int)(size)) +# define DEALLOCATE_LOCAL(ptr) /* as nothing */ +# else /* ! __GNUC__ */ + +/* + * warning: old mips alloca (pre 2.10) is unusable, new one is built in + * Test is easy, the new one is named __builtin_alloca and comes + * from alloca.h which #defines alloca. + */ +# ifndef NCR +# if defined(vax) || defined(sun) || defined(apollo) || defined(stellar) || defined(USL) || defined(alloca) +/* + * Some System V boxes extract alloca.o from /lib/libPW.a; if you + * decide that you don't want to use alloca, you might want to fix it here. + */ +/* alloca might be a macro taking one arg (hi, Sun!), so give it one. */ +# ifndef __sgi /* IRIX 5/6 has definition */ +# define __Xnullarg /* as nothing */ +# ifndef X_NOT_STDC_ENV + extern void *alloca(__Xnullarg); +# else + extern char *alloca(__Xnullarg); +# endif +# endif /* __sgi */ +# define ALLOCATE_LOCAL(size) alloca((int)(size)) +# define DEALLOCATE_LOCAL(ptr) /* as nothing */ +# endif /* who does alloca */ +# endif /* NCR */ +# endif /* __GNUC__ */ + +#endif /* NO_ALLOCA */ + +#if !defined(ALLOCATE_LOCAL) +# if defined(ALLOCATE_LOCAL_FALLBACK) && defined(DEALLOCATE_LOCAL_FALLBACK) +# define ALLOCATE_LOCAL(_size) ALLOCATE_LOCAL_FALLBACK(_size) +# define DEALLOCATE_LOCAL(_ptr) DEALLOCATE_LOCAL_FALLBACK(_ptr) +# else /* no fallbacks supplied; error */ +# define ALLOCATE_LOCAL(_size) ALLOCATE_LOCAL_FALLBACK undefined! +# define DEALLOCATE_LOCAL(_ptr) DEALLOCATE_LOCAL_FALLBACK undefined! +# endif /* defined(ALLOCATE_LOCAL_FALLBACK && DEALLOCATE_LOCAL_FALLBACK) */ +#endif /* !defined(ALLOCATE_LOCAL) */ + +#endif /* XALLOCA_H */ diff --git a/include/X11/Xfuncproto.h b/include/X11/Xfuncproto.h new file mode 100755 index 0000000..594d341 --- /dev/null +++ b/include/X11/Xfuncproto.h @@ -0,0 +1,88 @@ +/* $XConsortium: Xfuncproto.h,v 1.9 95/06/08 23:20:39 gildea Exp $ */ +/* + * +Copyright (c) 1989, 1991 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. + * + */ + +/* Definitions to make function prototypes manageable */ + +#ifndef _XFUNCPROTO_H_ +#define _XFUNCPROTO_H_ + +#ifndef NeedFunctionPrototypes +#if defined(FUNCPROTO) || defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus) +#define NeedFunctionPrototypes 1 +#else +#define NeedFunctionPrototypes 0 +#endif +#endif /* NeedFunctionPrototypes */ + +#ifndef NeedVarargsPrototypes +#if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus) || (FUNCPROTO&2) +#define NeedVarargsPrototypes 1 +#else +#define NeedVarargsPrototypes 0 +#endif +#endif /* NeedVarargsPrototypes */ + +#if NeedFunctionPrototypes + +#ifndef NeedNestedPrototypes +#if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus) || (FUNCPROTO&8) +#define NeedNestedPrototypes 1 +#else +#define NeedNestedPrototypes 0 +#endif +#endif /* NeedNestedPrototypes */ + +#ifndef _Xconst +#if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus) || (FUNCPROTO&4) +#define _Xconst const +#else +#define _Xconst +#endif +#endif /* _Xconst */ + +#ifndef NeedWidePrototypes +#ifdef NARROWPROTO +#define NeedWidePrototypes 0 +#else +#define NeedWidePrototypes 1 /* default to make interropt. easier */ +#endif +#endif /* NeedWidePrototypes */ + +#endif /* NeedFunctionPrototypes */ + +#ifndef _XFUNCPROTOBEGIN +#ifdef __cplusplus /* for C++ V2.0 */ +#define _XFUNCPROTOBEGIN extern "C" { /* do not leave open across includes */ +#define _XFUNCPROTOEND } +#else +#define _XFUNCPROTOBEGIN +#define _XFUNCPROTOEND +#endif +#endif /* _XFUNCPROTOBEGIN */ + +#endif /* _XFUNCPROTO_H_ */ diff --git a/include/X11/Xfuncs.h b/include/X11/Xfuncs.h new file mode 100755 index 0000000..aeebf85 --- /dev/null +++ b/include/X11/Xfuncs.h @@ -0,0 +1,98 @@ +/* + * $XConsortium: Xfuncs.h,v 1.16 94/12/01 16:25:53 kaleb Exp $ + * $XFree86: xc/include/Xfuncs.h,v 3.2 1995/01/28 15:42:03 dawes Exp $ + * + * +Copyright (c) 1990 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 _XFUNCS_H_ +#define _XFUNCS_H_ + +#include + +/* the old Xfuncs.h, for pre-R6 */ + +#ifdef X_USEBFUNCS +void bcopy(); +void bzero(); +int bcmp(); +#else +#if (__STDC__ && !defined(X_NOT_STDC_ENV) && !defined(sun) && !defined(macII) && !defined(apollo)) || defined(SVR4) || defined(hpux) || defined(_IBMR2) || defined(_SEQUENT_) +#include +#define _XFUNCS_H_INCLUDED_STRING_H +#define bcopy(b1,b2,len) memmove(b2, b1, (size_t)(len)) +#define bzero(b,len) memset(b, 0, (size_t)(len)) +#define bcmp(b1,b2,len) memcmp(b1, b2, (size_t)(len)) +#else +#ifdef sgi +#include +#else +#ifdef SYSV +#include +void bcopy(); +#define bzero(b,len) memset(b, 0, len) +#define bcmp(b1,b2,len) memcmp(b1, b2, len) +#else +#ifdef __EMX__ +#include +#define _XFUNCS_H_INCLUDED_STRING_H +/* bcopy, bcmp, bzero declared */ +#else /* bsd */ +void bcopy(); +void bzero(); +int bcmp(); +#endif +#endif /* SYSV */ +#endif /* sgi */ +#endif /* __STDC__ and relatives */ +#endif /* X_USEBFUNCS */ + +/* the new Xfuncs.h */ + +#if !defined(X_NOT_STDC_ENV) && (!defined(sun) || defined(SVR4)) +/* the ANSI C way */ +#ifndef _XFUNCS_H_INCLUDED_STRING_H +#include +#endif +#undef bzero +#define bzero(b,len) memset(b,0,len) +#else /* else X_NOT_STDC_ENV or SunOS 4 */ +#if defined(SYSV) || defined(luna) || defined(sun) || defined(__sxg__) +#include +#define memmove(dst,src,len) bcopy((char *)(src),(char *)(dst),(int)(len)) +#if defined(SYSV) && defined(_XBCOPYFUNC) +#undef memmove +#define memmove(dst,src,len) _XBCOPYFUNC((char *)(src),(char *)(dst),(int)(len)) +#define _XNEEDBCOPYFUNC +#endif +#else /* else vanilla BSD */ +#define memmove(dst,src,len) bcopy((char *)(src),(char *)(dst),(int)(len)) +#define memcpy(dst,src,len) bcopy((char *)(src),(char *)(dst),(int)(len)) +#define memcmp(b1,b2,len) bcmp((char *)(b1),(char *)(b2),(int)(len)) +#endif /* SYSV else */ +#endif /* ! X_NOT_STDC_ENV else */ + +#endif /* _XFUNCS_H_ */ diff --git a/include/X11/Xmd.h b/include/X11/Xmd.h new file mode 100755 index 0000000..5d2b85a --- /dev/null +++ b/include/X11/Xmd.h @@ -0,0 +1,206 @@ +/*********************************************************** + +Copyright (c) 1987 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. + + +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 XMD_H +#define XMD_H 1 +/* $XConsortium: Xmd.h,v 1.49 95/06/08 23:20:39 gildea Exp $ */ +/* $XFree86: xc/include/Xmd.h,v 3.4 1996/12/31 04:15:20 dawes Exp $ */ +/* + * Xmd.h: MACHINE DEPENDENT DECLARATIONS. + */ + +/* + * Special per-machine configuration flags. + */ +#ifdef CRAY +#define WORD64 /* 64-bit architecture */ +#endif +#if defined(__alpha) || defined(__alpha__) +#define LONG64 /* 32/64-bit architecture */ +#endif +#ifdef __sgi +#if (_MIPS_SZLONG == 64) +#define LONG64 +#endif +#endif + +/* + * Stuff to handle large architecture machines; the constants were generated + * on a 32-bit machine and must coorespond to the protocol. + */ +#ifdef WORD64 +#define MUSTCOPY +#endif /* WORD64 */ + + +/* + * Definition of macro used to set constants for size of network structures; + * machines with preprocessors that can't handle all of the sz_ symbols + * can define this macro to be sizeof(x) if and only if their compiler doesn't + * pad out structures (esp. the xTextElt structure which contains only two + * one-byte fields). Network structures should always define sz_symbols. + * + * The sz_ prefix is used instead of something more descriptive so that the + * symbols are no more than 32 characters long (which causes problems for some + * compilers and preprocessors). + * + * The extra indirection in the __STDC__ case is to get macro arguments to + * expand correctly before the concatenation, rather than afterward. + */ +#if ((defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus)) && !defined(UNIXCPP)) || defined(ANSICPP) +#define _SIZEOF(x) sz_##x +#define SIZEOF(x) _SIZEOF(x) +#else +#define SIZEOF(x) sz_/**/x +#endif /* if ANSI C compiler else not */ + +/* + * Bitfield suffixes for the protocol structure elements, if you + * need them. Note that bitfields are not guarranteed to be signed + * (or even unsigned) according to ANSI C. + */ +#ifdef WORD64 +typedef long INT64; +typedef unsigned long CARD64; +#define B32 :32 +#define B16 :16 +#ifdef UNSIGNEDBITFIELDS +typedef unsigned int INT32; +typedef unsigned int INT16; +#else +#ifdef __STDC__ +typedef signed int INT32; +typedef signed int INT16; +#else +typedef int INT32; +typedef int INT16; +#endif +#endif +#else +#define B32 +#define B16 +#ifdef LONG64 +typedef long INT64; +typedef int INT32; +#else +typedef long INT32; +#endif +typedef short INT16; +#endif + +#if defined(__STDC__) || defined(sgi) || defined(AIXV3) +typedef signed char INT8; +#else +typedef char INT8; +#endif + +#ifdef LONG64 +typedef unsigned long CARD64; +typedef unsigned int CARD32; +#else +typedef unsigned long CARD32; +#endif +typedef unsigned short CARD16; +typedef unsigned char CARD8; + +typedef CARD32 BITS32; +typedef CARD16 BITS16; + +#ifndef __EMX__ +typedef CARD8 BYTE; +typedef CARD8 BOOL; +#else +/* + * This is bad style, but the central include file declares them + * as well + */ +#define BYTE CARD8 +#define BOOL CARD8 +#endif + + +/* + * definitions for sign-extending bitfields on 64-bit architectures + */ +#if defined(WORD64) && defined(UNSIGNEDBITFIELDS) +#define cvtINT8toInt(val) (((val) & 0x00000080) ? ((val) | 0xffffffffffffff00) : (val)) +#define cvtINT16toInt(val) (((val) & 0x00008000) ? ((val) | 0xffffffffffff0000) : (val)) +#define cvtINT32toInt(val) (((val) & 0x80000000) ? ((val) | 0xffffffff00000000) : (val)) +#define cvtINT8toShort(val) cvtINT8toInt(val) +#define cvtINT16toShort(val) cvtINT16toInt(val) +#define cvtINT32toShort(val) cvtINT32toInt(val) +#define cvtINT8toLong(val) cvtINT8toInt(val) +#define cvtINT16toLong(val) cvtINT16toInt(val) +#define cvtINT32toLong(val) cvtINT32toInt(val) +#else +#define cvtINT8toInt(val) (val) +#define cvtINT16toInt(val) (val) +#define cvtINT32toInt(val) (val) +#define cvtINT8toShort(val) (val) +#define cvtINT16toShort(val) (val) +#define cvtINT32toShort(val) (val) +#define cvtINT8toLong(val) (val) +#define cvtINT16toLong(val) (val) +#define cvtINT32toLong(val) (val) +#endif /* WORD64 and UNSIGNEDBITFIELDS */ + + + +#ifdef MUSTCOPY +/* + * This macro must not cast or else pointers will get aligned and be wrong + */ +#define NEXTPTR(p,t) (((char *) p) + SIZEOF(t)) +#else /* else not MUSTCOPY, this is used for 32-bit machines */ +/* + * this version should leave result of type (t *), but that should only be + * used when not in MUSTCOPY + */ +#define NEXTPTR(p,t) (((t *)(p)) + 1) +#endif /* MUSTCOPY - used machines whose C structs don't line up with proto */ + +#endif /* XMD_H */ diff --git a/include/X11/Xos.h b/include/X11/Xos.h new file mode 100755 index 0000000..f2f0084 --- /dev/null +++ b/include/X11/Xos.h @@ -0,0 +1,317 @@ +/* + * $XConsortium: Xos.h /main/70 1996/11/15 16:00:41 kaleb $ + * $XFree86: xc/include/Xos.h,v 3.21.2.1 1998/01/23 12:35:11 dawes Exp $ + * + * +Copyright (c) 1987 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. + * + * The X Window System is a Trademark of X Consortium. + * + */ + +/* This is a collection of things to try and minimize system dependencies + * in a "signficant" number of source files. + */ + +#ifndef _XOS_H_ +#define _XOS_H_ + +#include + +/* + * Get major data types (esp. caddr_t) + */ + +#ifdef USG +#ifndef __TYPES__ +#ifdef CRAY +#define word word_t +#endif /* CRAY */ +#include /* forgot to protect it... */ +#define __TYPES__ +#endif /* __TYPES__ */ +#else /* USG */ +#if defined(_POSIX_SOURCE) && (defined(MOTOROLA) || defined(AMOEBA)) +#undef _POSIX_SOURCE +#include +#define _POSIX_SOURCE +#else +#include +#endif +#endif /* USG */ + + +/* + * Just about everyone needs the strings routines. We provide both forms here, + * index/rindex and strchr/strrchr, so any systems that don't provide them all + * need to have #defines here. + * + * NOTE: The following ISN'T true for this XFree86 version of this file. + * + * These macros are defined this way, rather than, e.g.: + * #defined index(s,c) strchr(s,c) + * because someone might be using them as function pointers, and such + * a change would break compatibility for anyone who's relying on them + * being the way they currently are. So we're stuck with them this way, + * which can be really inconvenient. :-( + */ + +#ifndef X_NOT_STDC_ENV + +#include +#ifdef __STDC__ +#ifndef index +#define index(s,c) (strchr((s),(c))) +#endif +#ifndef rindex +#define rindex(s,c) (strrchr((s),(c))) +#endif +#else +#ifndef index +#define index strchr +#endif +#ifndef rindex +#define rindex strrchr +#endif +#endif + +#else + +#ifdef SYSV +#if defined(clipper) || defined(__clipper__) +#include +#endif +#include +#define index strchr +#define rindex strrchr +#else +#include +#define strchr index +#define strrchr rindex +#endif + +#endif /* X_NOT_STDC_ENV */ + +/* + * strerror() + */ +#if (defined(X_NOT_STDC_ENV) || (defined(sun) && !defined(SVR4)) || defined(macII)) && !defined(__GLIBC__) +#ifndef strerror +extern char *sys_errlist[]; +extern int sys_nerr; +#define strerror(n) \ + (((n) >= 0 && (n) < sys_nerr) ? sys_errlist[n] : "unknown error") +#endif +#endif + +/* + * Get open(2) constants + */ +#ifdef X_NOT_POSIX +#include +#if defined(USL) || defined(CRAY) || defined(MOTOROLA) || (defined(i386) && (defined(SYSV) || defined(SVR4))) || defined(__sxg__) +#include +#endif +#ifdef WIN32 +#include +#else +#include +#endif +#else /* X_NOT_POSIX */ +#if !defined(_POSIX_SOURCE) && defined(macII) +#define _POSIX_SOURCE +#include +#include +#undef _POSIX_SOURCE +#else +#include +#include +#endif +#endif /* X_NOT_POSIX else */ + +#ifdef CSRG_BASED +#include +#include +#endif /* CSRG_BASED */ + +/* + * Get struct timeval + */ + +#ifdef SYSV + +#ifndef USL +#include +#endif +#include +#ifdef CRAY +#undef word +#endif /* CRAY */ +#if defined(USG) && !defined(CRAY) && !defined(MOTOROLA) && !defined(uniosu) && !defined(__sxg__) && !defined(clipper) && !defined(__clipper__) +struct timeval { + long tv_sec; + long tv_usec; +}; +#ifndef USL_SHARELIB +struct timezone { + int tz_minuteswest; + int tz_dsttime; +}; +#endif /* USL_SHARELIB */ +#endif /* USG */ + +#ifdef _SEQUENT_ +struct timezone { + int tz_minuteswest; + int tz_dsttime; +}; +#endif /* _SEQUENT_ */ + +#else /* not SYSV */ + +#if defined(_ANSI_SOURCE) && defined(__bsdi__) +#undef _ANSI_SOURCE +#include +#define _ANSI_SOURCE +#endif + +#if defined(_POSIX_SOURCE) && defined(SVR4) +/* need to omit _POSIX_SOURCE in order to get what we want in SVR4 */ +#undef _POSIX_SOURCE +#include +#define _POSIX_SOURCE +#else /* defined(_POSIX_SOURCE) && defined(SVR4) */ +#ifdef WIN32 +#include +#if !defined(_WINSOCKAPI_) && !defined(_WILLWINSOCK_) +struct timeval { + long tv_sec; /* seconds */ + long tv_usec; /* and microseconds */ +}; +#endif +#include +#define gettimeofday(t) \ +{ \ + struct _timeb _gtodtmp; \ + _ftime (&_gtodtmp); \ + (t)->tv_sec = _gtodtmp.time; \ + (t)->tv_usec = _gtodtmp.millitm * 1000; \ +} +#else /* WIN32 */ +#ifdef _SEQUENT_ +#include +#else /* _SEQUENT_ */ +#ifdef AMOEBA +#include +#include +#else /* AMOEBA */ +#ifdef MINIX +#include +#else /* !MINIX */ +#ifndef Lynx +#include +#else +#include +#endif /* Lynx */ +#endif /* MINIX */ +#endif /* AMOEBA */ +#endif /* _SEQUENT_ */ +#endif /* WIN32 else */ +#endif /* defined(_POSIX_SOURCE) && defined(SVR4) */ + +#endif /* SYSV */ + +/* define X_GETTIMEOFDAY macro, a portable gettimeofday() */ +#if defined(_XOPEN_XPG4) || defined(_XOPEN_UNIX) /* _XOPEN_UNIX is XPG4.2 */ +#define X_GETTIMEOFDAY(t) gettimeofday(t, (struct timezone*)0) +#else +#if defined(SVR4) || defined(VMS) || defined(WIN32) +#define X_GETTIMEOFDAY(t) gettimeofday(t) +#else +#define X_GETTIMEOFDAY(t) gettimeofday(t, (struct timezone*)0) +#endif +#endif /* XPG4 else */ + +#ifdef MINIX +#include +#include +#include +#include +#include + +struct sockaddr +{ + u16_t sa_family; + char sa_data[14]; +}; + +struct sockaddr_in +{ + u16_t sin_family; + u16_t sin_port; + struct + { + ipaddr_t s_addr; + } sin_addr; + char sin_zero[8]; +}; + +struct in_addr +{ + ipaddr_t s_addr; +}; + +typedef char *caddr_t; +typedef unsigned char u_char; +#endif /* MINIX */ + +#ifdef __EMX__ +typedef unsigned long fd_mask; +#endif + +/* use POSIX name for signal */ +#if defined(X_NOT_POSIX) && defined(SYSV) && !defined(SIGCHLD) && !defined(ISC) +#define SIGCHLD SIGCLD +#endif + +#ifdef ISC +#include +#include +#define NGROUPS 16 +#endif + +#if defined(ISC) || defined(__EMX__) +/* + * Some OS's may not have this + */ + +#define X_NO_SYS_UN 1 + +struct sockaddr_un { + short sun_family; + char sun_path[108]; +}; +#endif + +#endif /* _XOS_H_ */ diff --git a/include/X11/Xosdefs.h b/include/X11/Xosdefs.h new file mode 100755 index 0000000..864d537 --- /dev/null +++ b/include/X11/Xosdefs.h @@ -0,0 +1,128 @@ +/* + * O/S-dependent (mis)feature macro definitions + * + * $XConsortium: Xosdefs.h /main/16 1996/09/28 16:17:29 rws $ + * $XFree86: xc/include/Xosdefs.h,v 3.11 1996/12/23 05:58:09 dawes Exp $ + * +Copyright (c) 1991 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 _XOSDEFS_H_ +#define _XOSDEFS_H_ + +/* + * X_NOT_STDC_ENV means does not have ANSI C header files. Lack of this + * symbol does NOT mean that the system has stdarg.h. + * + * X_NOT_POSIX means does not have POSIX header files. Lack of this + * symbol does NOT mean that the POSIX environment is the default. + * You may still have to define _POSIX_SOURCE to get it. + */ + +#ifdef NOSTDHDRS +#define X_NOT_POSIX +#define X_NOT_STDC_ENV +#endif + +#ifdef sony +#if !defined(SYSTYPE_SYSV) && !defined(_SYSTYPE_SYSV) +#define X_NOT_POSIX +#endif +#endif + +#ifdef UTEK +#define X_NOT_POSIX +#define X_NOT_STDC_ENV +#endif + +#ifdef vax +#ifndef ultrix /* assume vanilla BSD */ +#define X_NOT_POSIX +#define X_NOT_STDC_ENV +#endif +#endif + +#ifdef luna +#define X_NOT_POSIX +#define X_NOT_STDC_ENV +#endif + +#ifdef Mips +#define X_NOT_POSIX +#define X_NOT_STDC_ENV +#endif + +#ifdef USL +#ifdef SYSV /* (release 3.2) */ +#define X_NOT_POSIX +#define X_NOT_STDC_ENV +#endif +#endif + +#ifdef i386 +#ifdef SYSV +#if !(defined(ISC) && defined(_POSIX_SOURCE)) +#ifndef SCO +#ifndef _SCO_DS /* SCO 5.0 has SVR4 header files */ +#define X_NOT_POSIX +#endif +#define X_NOT_STDC_ENV +#endif +#endif /* !(defined(ISC) && defined(_POSIX_SOURCE)) */ +#endif +#endif + +#ifdef MOTOROLA +#ifdef SYSV +#define X_NOT_STDC_ENV +#endif +#endif + +#ifdef sun +#ifdef SVR4 +/* define this to whatever it needs to be */ +#define X_POSIX_C_SOURCE 199300L +#endif +#endif + +#ifdef WIN32 +#ifndef _POSIX_ +#define X_NOT_POSIX +#endif +#endif + +#if defined(nec_ews_svr2) || defined(SX) || defined(PC_UX) +#define X_NOT_POSIX +#define X_NOT_STDC_ENV +#endif + +#ifdef __EMX__ +#define USGISH +/* EMX claims to be ANSI, so X_NOT_STDC_ENV does not hold */ +/* could have been provided as std flags as well */ +#define X_WCHAR +#define X_LOCALE +#endif + +#endif /* _XOSDEFS_H_ */ diff --git a/include/X11/Xproto.h b/include/X11/Xproto.h new file mode 100755 index 0000000..58e047b --- /dev/null +++ b/include/X11/Xproto.h @@ -0,0 +1,2130 @@ +/* + * $XConsortium: Xproto.h /main/21 1996/03/20 15:27:51 mor $ + */ + +/* Definitions for the X window system used by server and c bindings */ + +/* + * This packet-construction scheme makes the following assumptions: + * + * 1. The compiler is able + * to generate code which addresses one- and two-byte quantities. + * In the worst case, this would be done with bit-fields. If bit-fields + * are used it may be necessary to reorder the request fields in this file, + * depending on the order in which the machine assigns bit fields to + * machine words. There may also be a problem with sign extension, + * as K+R specify that bitfields are always unsigned. + * + * 2. 2- and 4-byte fields in packet structures must be ordered by hand + * such that they are naturally-aligned, so that no compiler will ever + * insert padding bytes. + * + * 3. All packets are hand-padded to a multiple of 4 bytes, for + * the same reason. + */ + +#ifndef XPROTO_H +#define XPROTO_H + +/*********************************************************** + +Copyright (c) 1987 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. + + +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 +#include + +/* + * Define constants for the sizes of the network packets. The sz_ prefix is + * used instead of something more descriptive so that the symbols are no more + * than 32 characters in length (which causes problems for some compilers). + */ +#define sz_xSegment 8 +#define sz_xPoint 4 +#define sz_xRectangle 8 +#define sz_xArc 12 +#define sz_xConnClientPrefix 12 +#define sz_xConnSetupPrefix 8 +#define sz_xConnSetup 32 +#define sz_xPixmapFormat 8 +#define sz_xDepth 8 +#define sz_xVisualType 24 +#define sz_xWindowRoot 40 +#define sz_xTimecoord 8 +#define sz_xHostEntry 4 +#define sz_xCharInfo 12 +#define sz_xFontProp 8 +#define sz_xTextElt 2 +#define sz_xColorItem 12 +#define sz_xrgb 8 +#define sz_xGenericReply 32 +#define sz_xGetWindowAttributesReply 44 +#define sz_xGetGeometryReply 32 +#define sz_xQueryTreeReply 32 +#define sz_xInternAtomReply 32 +#define sz_xGetAtomNameReply 32 +#define sz_xGetPropertyReply 32 +#define sz_xListPropertiesReply 32 +#define sz_xGetSelectionOwnerReply 32 +#define sz_xGrabPointerReply 32 +#define sz_xQueryPointerReply 32 +#define sz_xGetMotionEventsReply 32 +#define sz_xTranslateCoordsReply 32 +#define sz_xGetInputFocusReply 32 +#define sz_xQueryKeymapReply 40 +#define sz_xQueryFontReply 60 +#define sz_xQueryTextExtentsReply 32 +#define sz_xListFontsReply 32 +#define sz_xGetFontPathReply 32 +#define sz_xGetImageReply 32 +#define sz_xListInstalledColormapsReply 32 +#define sz_xAllocColorReply 32 +#define sz_xAllocNamedColorReply 32 +#define sz_xAllocColorCellsReply 32 +#define sz_xAllocColorPlanesReply 32 +#define sz_xQueryColorsReply 32 +#define sz_xLookupColorReply 32 +#define sz_xQueryBestSizeReply 32 +#define sz_xQueryExtensionReply 32 +#define sz_xListExtensionsReply 32 +#define sz_xSetMappingReply 32 +#define sz_xGetKeyboardControlReply 52 +#define sz_xGetPointerControlReply 32 +#define sz_xGetScreenSaverReply 32 +#define sz_xListHostsReply 32 +#define sz_xSetModifierMappingReply 32 +#define sz_xError 32 +#define sz_xEvent 32 +#define sz_xKeymapEvent 32 +#define sz_xReq 4 +#define sz_xResourceReq 8 +#define sz_xCreateWindowReq 32 +#define sz_xChangeWindowAttributesReq 12 +#define sz_xChangeSaveSetReq 8 +#define sz_xReparentWindowReq 16 +#define sz_xConfigureWindowReq 12 +#define sz_xCirculateWindowReq 8 +#define sz_xInternAtomReq 8 +#define sz_xChangePropertyReq 24 +#define sz_xDeletePropertyReq 12 +#define sz_xGetPropertyReq 24 +#define sz_xSetSelectionOwnerReq 16 +#define sz_xConvertSelectionReq 24 +#define sz_xSendEventReq 44 +#define sz_xGrabPointerReq 24 +#define sz_xGrabButtonReq 24 +#define sz_xUngrabButtonReq 12 +#define sz_xChangeActivePointerGrabReq 16 +#define sz_xGrabKeyboardReq 16 +#define sz_xGrabKeyReq 16 +#define sz_xUngrabKeyReq 12 +#define sz_xAllowEventsReq 8 +#define sz_xGetMotionEventsReq 16 +#define sz_xTranslateCoordsReq 16 +#define sz_xWarpPointerReq 24 +#define sz_xSetInputFocusReq 12 +#define sz_xOpenFontReq 12 +#define sz_xQueryTextExtentsReq 8 +#define sz_xListFontsReq 8 +#define sz_xSetFontPathReq 8 +#define sz_xCreatePixmapReq 16 +#define sz_xCreateGCReq 16 +#define sz_xChangeGCReq 12 +#define sz_xCopyGCReq 16 +#define sz_xSetDashesReq 12 +#define sz_xSetClipRectanglesReq 12 +#define sz_xCopyAreaReq 28 +#define sz_xCopyPlaneReq 32 +#define sz_xPolyPointReq 12 +#define sz_xPolySegmentReq 12 +#define sz_xFillPolyReq 16 +#define sz_xPutImageReq 24 +#define sz_xGetImageReq 20 +#define sz_xPolyTextReq 16 +#define sz_xImageTextReq 16 +#define sz_xCreateColormapReq 16 +#define sz_xCopyColormapAndFreeReq 12 +#define sz_xAllocColorReq 16 +#define sz_xAllocNamedColorReq 12 +#define sz_xAllocColorCellsReq 12 +#define sz_xAllocColorPlanesReq 16 +#define sz_xFreeColorsReq 12 +#define sz_xStoreColorsReq 8 +#define sz_xStoreNamedColorReq 16 +#define sz_xQueryColorsReq 8 +#define sz_xLookupColorReq 12 +#define sz_xCreateCursorReq 32 +#define sz_xCreateGlyphCursorReq 32 +#define sz_xRecolorCursorReq 20 +#define sz_xQueryBestSizeReq 12 +#define sz_xQueryExtensionReq 8 +#define sz_xChangeKeyboardControlReq 8 +#define sz_xBellReq 4 +#define sz_xChangePointerControlReq 12 +#define sz_xSetScreenSaverReq 12 +#define sz_xChangeHostsReq 8 +#define sz_xListHostsReq 4 +#define sz_xChangeModeReq 4 +#define sz_xRotatePropertiesReq 12 +#define sz_xReply 32 +#define sz_xGrabKeyboardReply 32 +#define sz_xListFontsWithInfoReply 60 +#define sz_xSetPointerMappingReply 32 +#define sz_xGetKeyboardMappingReply 32 +#define sz_xGetPointerMappingReply 32 +#define sz_xGetModifierMappingReply 32 +#define sz_xListFontsWithInfoReq 8 +#define sz_xPolyLineReq 12 +#define sz_xPolyArcReq 12 +#define sz_xPolyRectangleReq 12 +#define sz_xPolyFillRectangleReq 12 +#define sz_xPolyFillArcReq 12 +#define sz_xPolyText8Req 16 +#define sz_xPolyText16Req 16 +#define sz_xImageText8Req 16 +#define sz_xImageText16Req 16 +#define sz_xSetPointerMappingReq 4 +#define sz_xForceScreenSaverReq 4 +#define sz_xSetCloseDownModeReq 4 +#define sz_xClearAreaReq 16 +#define sz_xSetAccessControlReq 4 +#define sz_xGetKeyboardMappingReq 8 +#define sz_xSetModifierMappingReq 4 +#define sz_xPropIconSize 24 +#define sz_xChangeKeyboardMappingReq 8 + + +/* For the purpose of the structure definitions in this file, +we must redefine the following types in terms of Xmd.h's types, which may +include bit fields. All of these are #undef'd at the end of this file, +restoring the definitions in X.h. */ + +#define Window CARD32 +#define Drawable CARD32 +#define Font CARD32 +#define Pixmap CARD32 +#define Cursor CARD32 +#define Colormap CARD32 +#define GContext CARD32 +#define Atom CARD32 +#define VisualID CARD32 +#define Time CARD32 +#define KeyCode CARD8 +#define KeySym CARD32 + +#define X_TCP_PORT 6000 /* add display number */ + +#define xTrue 1 +#define xFalse 0 + + +typedef CARD16 KeyButMask; + +/***************** + connection setup structure. This is followed by + numRoots xWindowRoot structs. +*****************/ + +typedef struct { + CARD8 byteOrder; + BYTE pad; + CARD16 majorVersion B16, minorVersion B16; + CARD16 nbytesAuthProto B16; /* Authorization protocol */ + CARD16 nbytesAuthString B16; /* Authorization string */ + CARD16 pad2 B16; +} xConnClientPrefix; + +typedef struct { + CARD8 success; + BYTE lengthReason; /*num bytes in string following if failure */ + CARD16 majorVersion B16, + minorVersion B16; + CARD16 length B16; /* 1/4 additional bytes in setup info */ +} xConnSetupPrefix; + + +typedef struct { + CARD32 release B32; + CARD32 ridBase B32, + ridMask B32; + CARD32 motionBufferSize B32; + CARD16 nbytesVendor B16; /* number of bytes in vendor string */ + CARD16 maxRequestSize B16; + CARD8 numRoots; /* number of roots structs to follow */ + CARD8 numFormats; /* number of pixmap formats */ + CARD8 imageByteOrder; /* LSBFirst, MSBFirst */ + CARD8 bitmapBitOrder; /* LeastSignificant, MostSign...*/ + CARD8 bitmapScanlineUnit, /* 8, 16, 32 */ + bitmapScanlinePad; /* 8, 16, 32 */ + KeyCode minKeyCode, maxKeyCode; + CARD32 pad2 B32; +} xConnSetup; + +typedef struct { + CARD8 depth; + CARD8 bitsPerPixel; + CARD8 scanLinePad; + CARD8 pad1; + CARD32 pad2 B32; +} xPixmapFormat; + +/* window root */ + +typedef struct { + CARD8 depth; + CARD8 pad1; + CARD16 nVisuals B16; /* number of xVisualType structures following */ + CARD32 pad2 B32; + } xDepth; + +typedef struct { + VisualID visualID B32; +#if defined(__cplusplus) || defined(c_plusplus) + CARD8 c_class; +#else + CARD8 class; +#endif + CARD8 bitsPerRGB; + CARD16 colormapEntries B16; + CARD32 redMask B32, greenMask B32, blueMask B32; + CARD32 pad B32; + } xVisualType; + +typedef struct { + Window windowId B32; + Colormap defaultColormap B32; + CARD32 whitePixel B32, blackPixel B32; + CARD32 currentInputMask B32; + CARD16 pixWidth B16, pixHeight B16; + CARD16 mmWidth B16, mmHeight B16; + CARD16 minInstalledMaps B16, maxInstalledMaps B16; + VisualID rootVisualID B32; + CARD8 backingStore; + BOOL saveUnders; + CARD8 rootDepth; + CARD8 nDepths; /* number of xDepth structures following */ +} xWindowRoot; + + +/***************************************************************** + * Structure Defns + * Structures needed for replies + *****************************************************************/ + +/* Used in GetMotionEvents */ + +typedef struct { + CARD32 time B32; + INT16 x B16, y B16; +} xTimecoord; + +typedef struct { + CARD8 family; + BYTE pad; + CARD16 length B16; +} xHostEntry; + +typedef struct { + INT16 leftSideBearing B16, + rightSideBearing B16, + characterWidth B16, + ascent B16, + descent B16; + CARD16 attributes B16; +} xCharInfo; + +typedef struct { + Atom name B32; + CARD32 value B32; +} xFontProp; + +/* + * non-aligned big-endian font ID follows this struct + */ +typedef struct { /* followed by string */ + CARD8 len; /* number of *characters* in string, or FontChange (255) + for font change, or 0 if just delta given */ + INT8 delta; +} xTextElt; + + +typedef struct { + CARD32 pixel B32; + CARD16 red B16, green B16, blue B16; + CARD8 flags; /* DoRed, DoGreen, DoBlue booleans */ + CARD8 pad; +} xColorItem; + + +typedef struct { + CARD16 red B16, green B16, blue B16, pad B16; +} xrgb; + +typedef CARD8 KEYCODE; + + +/***************** + * XRep: + * meant to be 32 byte quantity + *****************/ + +/* GenericReply is the common format of all replies. The "data" items + are specific to each individual reply type. */ + +typedef struct { + BYTE type; /* X_Reply */ + BYTE data1; /* depends on reply type */ + CARD16 sequenceNumber B16; /* of last request received by server */ + CARD32 length B32; /* 4 byte quantities beyond size of GenericReply */ + CARD32 data00 B32; + CARD32 data01 B32; + CARD32 data02 B32; + CARD32 data03 B32; + CARD32 data04 B32; + CARD32 data05 B32; + } xGenericReply; + +/* Individual reply formats. */ + +typedef struct { + BYTE type; /* X_Reply */ + CARD8 backingStore; + CARD16 sequenceNumber B16; + CARD32 length B32; /* NOT 0; this is an extra-large reply */ + VisualID visualID B32; +#if defined(__cplusplus) || defined(c_plusplus) + CARD16 c_class B16; +#else + CARD16 class B16; +#endif + CARD8 bitGravity; + CARD8 winGravity; + CARD32 backingBitPlanes B32; + CARD32 backingPixel B32; + BOOL saveUnder; + BOOL mapInstalled; + CARD8 mapState; + BOOL override; + Colormap colormap B32; + CARD32 allEventMasks B32; + CARD32 yourEventMask B32; + CARD16 doNotPropagateMask B16; + CARD16 pad B16; + } xGetWindowAttributesReply; + +typedef struct { + BYTE type; /* X_Reply */ + CARD8 depth; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + Window root B32; + INT16 x B16, y B16; + CARD16 width B16, height B16; + CARD16 borderWidth B16; + CARD16 pad1 B16; + CARD32 pad2 B32; + CARD32 pad3 B32; + } xGetGeometryReply; + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + Window root B32, parent B32; + CARD16 nChildren B16; + CARD16 pad2 B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + } xQueryTreeReply; + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + Atom atom B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + } xInternAtomReply; + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* of additional bytes */ + CARD16 nameLength B16; /* # of characters in name */ + CARD16 pad2 B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + } xGetAtomNameReply; + +typedef struct { + BYTE type; /* X_Reply */ + CARD8 format; + CARD16 sequenceNumber B16; + CARD32 length B32; /* of additional bytes */ + Atom propertyType B32; + CARD32 bytesAfter B32; + CARD32 nItems B32; /* # of 8, 16, or 32-bit entities in reply */ + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + } xGetPropertyReply; + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 nProperties B16; + CARD16 pad2 B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + } xListPropertiesReply; + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + Window owner B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + } xGetSelectionOwnerReply; + +typedef struct { + BYTE type; /* X_Reply */ + BYTE status; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + } xGrabPointerReply; + +typedef xGrabPointerReply xGrabKeyboardReply; + +typedef struct { + BYTE type; /* X_Reply */ + BOOL sameScreen; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + Window root B32, child B32; + INT16 rootX B16, rootY B16, winX B16, winY B16; + CARD16 mask B16; + CARD16 pad1 B16; + CARD32 pad B32; + } xQueryPointerReply; + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 nEvents B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + } xGetMotionEventsReply; + +typedef struct { + BYTE type; /* X_Reply */ + BOOL sameScreen; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + Window child B32; + INT16 dstX B16, dstY B16; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + } xTranslateCoordsReply; + +typedef struct { + BYTE type; /* X_Reply */ + CARD8 revertTo; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + Window focus B32; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + } xGetInputFocusReply; + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 2, NOT 0; this is an extra-large reply */ + BYTE map[32]; + } xQueryKeymapReply; + +/* Warning: this MUST match (up to component renaming) xListFontsWithInfoReply */ +typedef struct _xQueryFontReply { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* definitely > 0, even if "nCharInfos" is 0 */ + xCharInfo minBounds; +#ifndef WORD64 + CARD32 walign1 B32; +#endif + xCharInfo maxBounds; +#ifndef WORD64 + CARD32 walign2 B32; +#endif + CARD16 minCharOrByte2 B16, maxCharOrByte2 B16; + CARD16 defaultChar B16; + CARD16 nFontProps B16; /* followed by this many xFontProp structures */ + CARD8 drawDirection; + CARD8 minByte1, maxByte1; + BOOL allCharsExist; + INT16 fontAscent B16, fontDescent B16; + CARD32 nCharInfos B32; /* followed by this many xCharInfo structures */ +} xQueryFontReply; + +typedef struct { + BYTE type; /* X_Reply */ + CARD8 drawDirection; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + INT16 fontAscent B16, fontDescent B16; + INT16 overallAscent B16, overallDescent B16; + INT32 overallWidth B32, overallLeft B32, overallRight B32; + CARD32 pad B32; + } xQueryTextExtentsReply; + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 nFonts B16; + CARD16 pad2 B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + } xListFontsReply; + +/* Warning: this MUST match (up to component renaming) xQueryFontReply */ +typedef struct { + BYTE type; /* X_Reply */ + CARD8 nameLength; /* 0 indicates end-of-reply-sequence */ + CARD16 sequenceNumber B16; + CARD32 length B32; /* definitely > 0, even if "nameLength" is 0 */ + xCharInfo minBounds; +#ifndef WORD64 + CARD32 walign1 B32; +#endif + xCharInfo maxBounds; +#ifndef WORD64 + CARD32 walign2 B32; +#endif + CARD16 minCharOrByte2 B16, maxCharOrByte2 B16; + CARD16 defaultChar B16; + CARD16 nFontProps B16; /* followed by this many xFontProp structures */ + CARD8 drawDirection; + CARD8 minByte1, maxByte1; + BOOL allCharsExist; + INT16 fontAscent B16, fontDescent B16; + CARD32 nReplies B32; /* hint as to how many more replies might be coming */ +} xListFontsWithInfoReply; + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 nPaths B16; + CARD16 pad2 B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + } xGetFontPathReply; + +typedef struct { + BYTE type; /* X_Reply */ + CARD8 depth; + CARD16 sequenceNumber B16; + CARD32 length B32; + VisualID visual B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + } xGetImageReply; + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 nColormaps B16; + CARD16 pad2 B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + } xListInstalledColormapsReply; + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + CARD16 red B16, green B16, blue B16; + CARD16 pad2 B16; + CARD32 pixel B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + } xAllocColorReply; + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + CARD32 pixel B32; + CARD16 exactRed B16, exactGreen B16, exactBlue B16; + CARD16 screenRed B16, screenGreen B16, screenBlue B16; + CARD32 pad2 B32; + CARD32 pad3 B32; + } xAllocNamedColorReply; + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 nPixels B16, nMasks B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + } xAllocColorCellsReply; + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 nPixels B16; + CARD16 pad2 B16; + CARD32 redMask B32, greenMask B32, blueMask B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + } xAllocColorPlanesReply; + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 nColors B16; + CARD16 pad2 B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + } xQueryColorsReply; + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + CARD16 exactRed B16, exactGreen B16, exactBlue B16; + CARD16 screenRed B16, screenGreen B16, screenBlue B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + } xLookupColorReply; + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + CARD16 width B16, height B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + } xQueryBestSizeReply; + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + BOOL present; + CARD8 major_opcode; + CARD8 first_event; + CARD8 first_error; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + } xQueryExtensionReply; + +typedef struct { + BYTE type; /* X_Reply */ + CARD8 nExtensions; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + } xListExtensionsReply; + + +typedef struct { + BYTE type; /* X_Reply */ + CARD8 success; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + } xSetMappingReply; +typedef xSetMappingReply xSetPointerMappingReply; +typedef xSetMappingReply xSetModifierMappingReply; + +typedef struct { + BYTE type; /* X_Reply */ + CARD8 nElts; /* how many elements does the map have */ + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + } xGetPointerMappingReply; + +typedef struct { + BYTE type; + CARD8 keySymsPerKeyCode; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xGetKeyboardMappingReply; + +typedef struct { + BYTE type; + CARD8 numKeyPerModifier; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xGetModifierMappingReply; + +typedef struct { + BYTE type; /* X_Reply */ + BOOL globalAutoRepeat; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 5 */ + CARD32 ledMask B32; + CARD8 keyClickPercent, bellPercent; + CARD16 bellPitch B16, bellDuration B16; + CARD16 pad B16; + BYTE map[32]; /* bit masks start here */ + } xGetKeyboardControlReply; + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + CARD16 accelNumerator B16, accelDenominator B16; + CARD16 threshold B16; + CARD16 pad2 B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + } xGetPointerControlReply; + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + CARD16 timeout B16, interval B16; + BOOL preferBlanking; + BOOL allowExposures; + CARD16 pad2 B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + } xGetScreenSaverReply; + +typedef struct { + BYTE type; /* X_Reply */ + BOOL enabled; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 nHosts B16; + CARD16 pad1 B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + } xListHostsReply; + + + + +/***************************************************************** + * Xerror + * All errors are 32 bytes + *****************************************************************/ + +typedef struct { + BYTE type; /* X_Error */ + BYTE errorCode; + CARD16 sequenceNumber B16; /* the nth request from this client */ + CARD32 resourceID B32; + CARD16 minorCode B16; + CARD8 majorCode; + BYTE pad1; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xError; + +/***************************************************************** + * xEvent + * All events are 32 bytes + *****************************************************************/ + +typedef struct _xEvent { + union { + struct { + BYTE type; + BYTE detail; + CARD16 sequenceNumber B16; + } u; + struct { + CARD32 pad00 B32; + Time time B32; + Window root B32, event B32, child B32; + INT16 rootX B16, rootY B16, eventX B16, eventY B16; + KeyButMask state B16; + BOOL sameScreen; + BYTE pad1; + } keyButtonPointer; + struct { + CARD32 pad00 B32; + Time time B32; + Window root B32, event B32, child B32; + INT16 rootX B16, rootY B16, eventX B16, eventY B16; + KeyButMask state B16; + BYTE mode; /* really XMode */ + BYTE flags; /* sameScreen and focus booleans, packed together */ +#define ELFlagFocus (1<<0) +#define ELFlagSameScreen (1<<1) + } enterLeave; + struct { + CARD32 pad00 B32; + Window window B32; + BYTE mode; /* really XMode */ + BYTE pad1, pad2, pad3; + } focus; + struct { + CARD32 pad00 B32; + Window window B32; + CARD16 x B16, y B16, width B16, height B16; + CARD16 count B16; + CARD16 pad2 B16; + } expose; + struct { + CARD32 pad00 B32; + Drawable drawable B32; + CARD16 x B16, y B16, width B16, height B16; + CARD16 minorEvent B16; + CARD16 count B16; + BYTE majorEvent; + BYTE pad1, pad2, pad3; + } graphicsExposure; + struct { + CARD32 pad00 B32; + Drawable drawable B32; + CARD16 minorEvent B16; + BYTE majorEvent; + BYTE bpad; + } noExposure; + struct { + CARD32 pad00 B32; + Window window B32; + CARD8 state; + BYTE pad1, pad2, pad3; + } visibility; + struct { + CARD32 pad00 B32; + Window parent B32, window B32; + INT16 x B16, y B16; + CARD16 width B16, height B16, borderWidth B16; + BOOL override; + BYTE bpad; + } createNotify; +/* + * The event feilds in the structures for DestroyNotify, UnmapNotify, + * MapNotify, ReparentNotify, ConfigureNotify, CirclulateNotify, GravityNotify, + * must be at the same offset because server internal code is depending upon + * this to patch up the events before they are delivered. + * Also note that MapRequest, ConfigureRequest and CirculateRequest have + * the same offset for the event window. + */ + struct { + CARD32 pad00 B32; + Window event B32, window B32; + } destroyNotify; + struct { + CARD32 pad00 B32; + Window event B32, window B32; + BOOL fromConfigure; + BYTE pad1, pad2, pad3; + } unmapNotify; + struct { + CARD32 pad00 B32; + Window event B32, window B32; + BOOL override; + BYTE pad1, pad2, pad3; + } mapNotify; + struct { + CARD32 pad00 B32; + Window parent B32, window B32; + } mapRequest; + struct { + CARD32 pad00 B32; + Window event B32, window B32, parent B32; + INT16 x B16, y B16; + BOOL override; + BYTE pad1, pad2, pad3; + } reparent; + struct { + CARD32 pad00 B32; + Window event B32, window B32, aboveSibling B32; + INT16 x B16, y B16; + CARD16 width B16, height B16, borderWidth B16; + BOOL override; + BYTE bpad; + } configureNotify; + struct { + CARD32 pad00 B32; + Window parent B32, window B32, sibling B32; + INT16 x B16, y B16; + CARD16 width B16, height B16, borderWidth B16; + CARD16 valueMask B16; + CARD32 pad1 B32; + } configureRequest; + struct { + CARD32 pad00 B32; + Window event B32, window B32; + INT16 x B16, y B16; + CARD32 pad1 B32, pad2 B32, pad3 B32, pad4 B32; + } gravity; + struct { + CARD32 pad00 B32; + Window window B32; + CARD16 width B16, height B16; + } resizeRequest; + struct { +/* The event field in the circulate record is really the parent when this + is used as a CirculateRequest insteaad of a CircluateNotify */ + CARD32 pad00 B32; + Window event B32, window B32, parent B32; + BYTE place; /* Top or Bottom */ + BYTE pad1, pad2, pad3; + } circulate; + struct { + CARD32 pad00 B32; + Window window B32; + Atom atom B32; + Time time B32; + BYTE state; /* NewValue or Deleted */ + BYTE pad1; + CARD16 pad2 B16; + } property; + struct { + CARD32 pad00 B32; + Time time B32; + Window window B32; + Atom atom B32; + } selectionClear; + struct { + CARD32 pad00 B32; + Time time B32; + Window owner B32, requestor B32; + Atom selection B32, target B32, property B32; + } selectionRequest; + struct { + CARD32 pad00 B32; + Time time B32; + Window requestor B32; + Atom selection B32, target B32, property B32; + } selectionNotify; + struct { + CARD32 pad00 B32; + Window window B32; + Colormap colormap B32; +#if defined(__cplusplus) || defined(c_plusplus) + BOOL c_new; +#else + BOOL new; +#endif + BYTE state; /* Installed or UnInstalled */ + BYTE pad1, pad2; + } colormap; + struct { + CARD32 pad00 B32; + CARD8 request; + KeyCode firstKeyCode; + CARD8 count; + BYTE pad1; + } mappingNotify; + struct { + CARD32 pad00 B32; + Window window B32; + union { + struct { + Atom type B32; + INT32 longs0 B32; + INT32 longs1 B32; + INT32 longs2 B32; + INT32 longs3 B32; + INT32 longs4 B32; + } l; + struct { + Atom type B32; + INT16 shorts0 B16; + INT16 shorts1 B16; + INT16 shorts2 B16; + INT16 shorts3 B16; + INT16 shorts4 B16; + INT16 shorts5 B16; + INT16 shorts6 B16; + INT16 shorts7 B16; + INT16 shorts8 B16; + INT16 shorts9 B16; + } s; + struct { + Atom type B32; + INT8 bytes[20]; + } b; + } u; + } clientMessage; + } u; +} xEvent; + +/* KeymapNotify events are not included in the above union because they + are different from all other events: they do not have a "detail" + or "sequenceNumber", so there is room for a 248-bit key mask. */ + +typedef struct { + BYTE type; + BYTE map[31]; + } xKeymapEvent; + +#define XEventSize (sizeof(xEvent)) + +/* XReply is the union of all the replies above whose "fixed part" +fits in 32 bytes. It does NOT include GetWindowAttributesReply, +QueryFontReply, QueryKeymapReply, or GetKeyboardControlReply +ListFontsWithInfoReply */ + +typedef union { + xGenericReply generic; + xGetGeometryReply geom; + xQueryTreeReply tree; + xInternAtomReply atom; + xGetAtomNameReply atomName; + xGetPropertyReply property; + xListPropertiesReply listProperties; + xGetSelectionOwnerReply selection; + xGrabPointerReply grabPointer; + xGrabKeyboardReply grabKeyboard; + xQueryPointerReply pointer; + xGetMotionEventsReply motionEvents; + xTranslateCoordsReply coords; + xGetInputFocusReply inputFocus; + xQueryTextExtentsReply textExtents; + xListFontsReply fonts; + xGetFontPathReply fontPath; + xGetImageReply image; + xListInstalledColormapsReply colormaps; + xAllocColorReply allocColor; + xAllocNamedColorReply allocNamedColor; + xAllocColorCellsReply colorCells; + xAllocColorPlanesReply colorPlanes; + xQueryColorsReply colors; + xLookupColorReply lookupColor; + xQueryBestSizeReply bestSize; + xQueryExtensionReply extension; + xListExtensionsReply extensions; + xSetModifierMappingReply setModifierMapping; + xGetModifierMappingReply getModifierMapping; + xSetPointerMappingReply setPointerMapping; + xGetKeyboardMappingReply getKeyboardMapping; + xGetPointerMappingReply getPointerMapping; + xGetPointerControlReply pointerControl; + xGetScreenSaverReply screenSaver; + xListHostsReply hosts; + xError error; + xEvent event; +} xReply; + + + +/***************************************************************** + * REQUESTS + *****************************************************************/ + + +/* Request structure */ + +typedef struct _xReq { + CARD8 reqType; + CARD8 data; /* meaning depends on request type */ + CARD16 length B16; /* length in 4 bytes quantities + of whole request, including this header */ +} xReq; + +/***************************************************************** + * structures that follow request. + *****************************************************************/ + +/* ResourceReq is used for any request which has a resource ID + (or Atom or Time) as its one and only argument. */ + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + CARD32 id B32; /* a Window, Drawable, Font, GContext, Pixmap, etc. */ + } xResourceReq; + +typedef struct { + CARD8 reqType; + CARD8 depth; + CARD16 length B16; + Window wid B32, parent B32; + INT16 x B16, y B16; + CARD16 width B16, height B16, borderWidth B16; +#if defined(__cplusplus) || defined(c_plusplus) + CARD16 c_class B16; +#else + CARD16 class B16; +#endif + VisualID visual B32; + CARD32 mask B32; +} xCreateWindowReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Window window B32; + CARD32 valueMask B32; +} xChangeWindowAttributesReq; + +typedef struct { + CARD8 reqType; + BYTE mode; + CARD16 length B16; + Window window B32; +} xChangeSaveSetReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Window window B32, parent B32; + INT16 x B16, y B16; +} xReparentWindowReq; + +typedef struct { + CARD8 reqType; + CARD8 pad; + CARD16 length B16; + Window window B32; + CARD16 mask B16; + CARD16 pad2 B16; +} xConfigureWindowReq; + +typedef struct { + CARD8 reqType; + CARD8 direction; + CARD16 length B16; + Window window B32; +} xCirculateWindowReq; + +typedef struct { /* followed by padded string */ + CARD8 reqType; + BOOL onlyIfExists; + CARD16 length B16; + CARD16 nbytes B16; /* number of bytes in string */ + CARD16 pad B16; +} xInternAtomReq; + +typedef struct { + CARD8 reqType; + CARD8 mode; + CARD16 length B16; + Window window B32; + Atom property B32, type B32; + CARD8 format; + BYTE pad[3]; + CARD32 nUnits B32; /* length of stuff following, depends on format */ +} xChangePropertyReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Window window B32; + Atom property B32; +} xDeletePropertyReq; + +typedef struct { + CARD8 reqType; +#if defined(__cplusplus) || defined(c_plusplus) + BOOL c_delete; +#else + BOOL delete; +#endif + CARD16 length B16; + Window window B32; + Atom property B32, type B32; + CARD32 longOffset B32; + CARD32 longLength B32; +} xGetPropertyReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Window window B32; + Atom selection B32; + Time time B32; +} xSetSelectionOwnerReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Window requestor B32; + Atom selection B32, target B32, property B32; + Time time B32; + } xConvertSelectionReq; + +typedef struct { + CARD8 reqType; + BOOL propagate; + CARD16 length B16; + Window destination B32; + CARD32 eventMask B32; +#ifdef WORD64 + /* the structure should have been quad-aligned */ + BYTE eventdata[SIZEOF(xEvent)]; +#else + xEvent event; +#endif /* WORD64 */ +} xSendEventReq; + +typedef struct { + CARD8 reqType; + BOOL ownerEvents; + CARD16 length B16; + Window grabWindow B32; + CARD16 eventMask B16; + BYTE pointerMode, keyboardMode; + Window confineTo B32; + Cursor cursor B32; + Time time B32; +} xGrabPointerReq; + +typedef struct { + CARD8 reqType; + BOOL ownerEvents; + CARD16 length B16; + Window grabWindow B32; + CARD16 eventMask B16; + BYTE pointerMode, keyboardMode; + Window confineTo B32; + Cursor cursor B32; + CARD8 button; + BYTE pad; + CARD16 modifiers B16; +} xGrabButtonReq; + +typedef struct { + CARD8 reqType; + CARD8 button; + CARD16 length B16; + Window grabWindow B32; + CARD16 modifiers B16; + CARD16 pad B16; +} xUngrabButtonReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Cursor cursor B32; + Time time B32; + CARD16 eventMask B16; + CARD16 pad2 B16; +} xChangeActivePointerGrabReq; + +typedef struct { + CARD8 reqType; + BOOL ownerEvents; + CARD16 length B16; + Window grabWindow B32; + Time time B32; + BYTE pointerMode, keyboardMode; + CARD16 pad B16; +} xGrabKeyboardReq; + +typedef struct { + CARD8 reqType; + BOOL ownerEvents; + CARD16 length B16; + Window grabWindow B32; + CARD16 modifiers B16; + CARD8 key; + BYTE pointerMode, keyboardMode; + BYTE pad1, pad2, pad3; +} xGrabKeyReq; + +typedef struct { + CARD8 reqType; + CARD8 key; + CARD16 length B16; + Window grabWindow B32; + CARD16 modifiers B16; + CARD16 pad B16; +} xUngrabKeyReq; + +typedef struct { + CARD8 reqType; + CARD8 mode; + CARD16 length B16; + Time time B32; +} xAllowEventsReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Window window B32; + Time start B32, stop B32; +} xGetMotionEventsReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Window srcWid B32, dstWid B32; + INT16 srcX B16, srcY B16; +} xTranslateCoordsReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Window srcWid B32, dstWid B32; + INT16 srcX B16, srcY B16; + CARD16 srcWidth B16, srcHeight B16; + INT16 dstX B16, dstY B16; +} xWarpPointerReq; + +typedef struct { + CARD8 reqType; + CARD8 revertTo; + CARD16 length B16; + Window focus B32; + Time time B32; +} xSetInputFocusReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Font fid B32; + CARD16 nbytes B16; + BYTE pad1, pad2; /* string follows on word boundary */ +} xOpenFontReq; + +typedef struct { + CARD8 reqType; + BOOL oddLength; + CARD16 length B16; + Font fid B32; + } xQueryTextExtentsReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + CARD16 maxNames B16; + CARD16 nbytes B16; /* followed immediately by string bytes */ +} xListFontsReq; + +typedef xListFontsReq xListFontsWithInfoReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + CARD16 nFonts B16; + BYTE pad1, pad2; /* LISTofSTRING8 follows on word boundary */ +} xSetFontPathReq; + +typedef struct { + CARD8 reqType; + CARD8 depth; + CARD16 length B16; + Pixmap pid B32; + Drawable drawable B32; + CARD16 width B16, height B16; +} xCreatePixmapReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + GContext gc B32; + Drawable drawable B32; + CARD32 mask B32; +} xCreateGCReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + GContext gc B32; + CARD32 mask B32; +} xChangeGCReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + GContext srcGC B32, dstGC B32; + CARD32 mask B32; +} xCopyGCReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + GContext gc B32; + CARD16 dashOffset B16; + CARD16 nDashes B16; /* length LISTofCARD8 of values following */ +} xSetDashesReq; + +typedef struct { + CARD8 reqType; + BYTE ordering; + CARD16 length B16; + GContext gc B32; + INT16 xOrigin B16, yOrigin B16; +} xSetClipRectanglesReq; + +typedef struct { + CARD8 reqType; + BOOL exposures; + CARD16 length B16; + Window window B32; + INT16 x B16, y B16; + CARD16 width B16, height B16; +} xClearAreaReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Drawable srcDrawable B32, dstDrawable B32; + GContext gc B32; + INT16 srcX B16, srcY B16, dstX B16, dstY B16; + CARD16 width B16, height B16; +} xCopyAreaReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Drawable srcDrawable B32, dstDrawable B32; + GContext gc B32; + INT16 srcX B16, srcY B16, dstX B16, dstY B16; + CARD16 width B16, height B16; + CARD32 bitPlane B32; +} xCopyPlaneReq; + +typedef struct { + CARD8 reqType; + BYTE coordMode; + CARD16 length B16; + Drawable drawable B32; + GContext gc B32; +} xPolyPointReq; + +typedef xPolyPointReq xPolyLineReq; /* same request structure */ + +/* The following used for PolySegment, PolyRectangle, PolyArc, PolyFillRectangle, PolyFillArc */ + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Drawable drawable B32; + GContext gc B32; +} xPolySegmentReq; + +typedef xPolySegmentReq xPolyArcReq; +typedef xPolySegmentReq xPolyRectangleReq; +typedef xPolySegmentReq xPolyFillRectangleReq; +typedef xPolySegmentReq xPolyFillArcReq; + +typedef struct _FillPolyReq { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Drawable drawable B32; + GContext gc B32; + BYTE shape; + BYTE coordMode; + CARD16 pad1 B16; +} xFillPolyReq; + + +typedef struct _PutImageReq { + CARD8 reqType; + CARD8 format; + CARD16 length B16; + Drawable drawable B32; + GContext gc B32; + CARD16 width B16, height B16; + INT16 dstX B16, dstY B16; + CARD8 leftPad; + CARD8 depth; + CARD16 pad B16; +} xPutImageReq; + +typedef struct { + CARD8 reqType; + CARD8 format; + CARD16 length B16; + Drawable drawable B32; + INT16 x B16, y B16; + CARD16 width B16, height B16; + CARD32 planeMask B32; +} xGetImageReq; + +/* the folloiwng used by PolyText8 and PolyText16 */ + +typedef struct { + CARD8 reqType; + CARD8 pad; + CARD16 length B16; + Drawable drawable B32; + GContext gc B32; + INT16 x B16, y B16; /* items (xTextElt) start after struct */ +} xPolyTextReq; + +typedef xPolyTextReq xPolyText8Req; +typedef xPolyTextReq xPolyText16Req; + +typedef struct { + CARD8 reqType; + BYTE nChars; + CARD16 length B16; + Drawable drawable B32; + GContext gc B32; + INT16 x B16, y B16; +} xImageTextReq; + +typedef xImageTextReq xImageText8Req; +typedef xImageTextReq xImageText16Req; + +typedef struct { + CARD8 reqType; + BYTE alloc; + CARD16 length B16; + Colormap mid B32; + Window window B32; + VisualID visual B32; +} xCreateColormapReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Colormap mid B32; + Colormap srcCmap B32; +} xCopyColormapAndFreeReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Colormap cmap B32; + CARD16 red B16, green B16, blue B16; + CARD16 pad2 B16; +} xAllocColorReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Colormap cmap B32; + CARD16 nbytes B16; /* followed by structure */ + BYTE pad1, pad2; +} xAllocNamedColorReq; + +typedef struct { + CARD8 reqType; + BOOL contiguous; + CARD16 length B16; + Colormap cmap B32; + CARD16 colors B16, planes B16; +} xAllocColorCellsReq; + +typedef struct { + CARD8 reqType; + BOOL contiguous; + CARD16 length B16; + Colormap cmap B32; + CARD16 colors B16, red B16, green B16, blue B16; +} xAllocColorPlanesReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Colormap cmap B32; + CARD32 planeMask B32; +} xFreeColorsReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Colormap cmap B32; +} xStoreColorsReq; + +typedef struct { + CARD8 reqType; + CARD8 flags; /* DoRed, DoGreen, DoBlue, as in xColorItem */ + CARD16 length B16; + Colormap cmap B32; + CARD32 pixel B32; + CARD16 nbytes B16; /* number of name string bytes following structure */ + BYTE pad1, pad2; + } xStoreNamedColorReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Colormap cmap B32; +} xQueryColorsReq; + +typedef struct { /* followed by string of length len */ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Colormap cmap B32; + CARD16 nbytes B16; /* number of string bytes following structure*/ + BYTE pad1, pad2; +} xLookupColorReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Cursor cid B32; + Pixmap source B32, mask B32; + CARD16 foreRed B16, foreGreen B16, foreBlue B16; + CARD16 backRed B16, backGreen B16, backBlue B16; + CARD16 x B16, y B16; +} xCreateCursorReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Cursor cid B32; + Font source B32, mask B32; + CARD16 sourceChar B16, maskChar B16; + CARD16 foreRed B16, foreGreen B16, foreBlue B16; + CARD16 backRed B16, backGreen B16, backBlue B16; +} xCreateGlyphCursorReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Cursor cursor B32; + CARD16 foreRed B16, foreGreen B16, foreBlue B16; + CARD16 backRed B16, backGreen B16, backBlue B16; +} xRecolorCursorReq; + +typedef struct { + CARD8 reqType; +#if defined(__cplusplus) || defined(c_plusplus) + CARD8 c_class; +#else + CARD8 class; +#endif + CARD16 length B16; + Drawable drawable B32; + CARD16 width B16, height B16; +} xQueryBestSizeReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + CARD16 nbytes B16; /* number of string bytes following structure */ + BYTE pad1, pad2; +} xQueryExtensionReq; + +typedef struct { + CARD8 reqType; + CARD8 numKeyPerModifier; + CARD16 length B16; +} xSetModifierMappingReq; + +typedef struct { + CARD8 reqType; + CARD8 nElts; /* how many elements in the map */ + CARD16 length B16; +} xSetPointerMappingReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + KeyCode firstKeyCode; + CARD8 count; + CARD16 pad1 B16; +} xGetKeyboardMappingReq; + +typedef struct { + CARD8 reqType; + CARD8 keyCodes; + CARD16 length B16; + KeyCode firstKeyCode; + CARD8 keySymsPerKeyCode; + CARD16 pad1 B16; +} xChangeKeyboardMappingReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + CARD32 mask B32; +} xChangeKeyboardControlReq; + +typedef struct { + CARD8 reqType; + INT8 percent; /* -100 to 100 */ + CARD16 length B16; +} xBellReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + INT16 accelNum B16, accelDenum B16; + INT16 threshold B16; + BOOL doAccel, doThresh; +} xChangePointerControlReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + INT16 timeout B16, interval B16; + BYTE preferBlank, allowExpose; + CARD16 pad2 B16; +} xSetScreenSaverReq; + +typedef struct { + CARD8 reqType; + BYTE mode; + CARD16 length B16; + CARD8 hostFamily; + BYTE pad; + CARD16 hostLength B16; +} xChangeHostsReq; + +typedef struct { + CARD8 reqType; + BYTE pad; + CARD16 length B16; + } xListHostsReq; + +typedef struct { + CARD8 reqType; + BYTE mode; + CARD16 length B16; + } xChangeModeReq; + +typedef xChangeModeReq xSetAccessControlReq; +typedef xChangeModeReq xSetCloseDownModeReq; +typedef xChangeModeReq xForceScreenSaverReq; + +typedef struct { /* followed by LIST of ATOM */ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Window window B32; + CARD16 nAtoms B16; + INT16 nPositions B16; + } xRotatePropertiesReq; + + + +/* Reply codes */ + +#define X_Reply 1 /* Normal reply */ +#define X_Error 0 /* Error */ + +/* Request codes */ + +#define X_CreateWindow 1 +#define X_ChangeWindowAttributes 2 +#define X_GetWindowAttributes 3 +#define X_DestroyWindow 4 +#define X_DestroySubwindows 5 +#define X_ChangeSaveSet 6 +#define X_ReparentWindow 7 +#define X_MapWindow 8 +#define X_MapSubwindows 9 +#define X_UnmapWindow 10 +#define X_UnmapSubwindows 11 +#define X_ConfigureWindow 12 +#define X_CirculateWindow 13 +#define X_GetGeometry 14 +#define X_QueryTree 15 +#define X_InternAtom 16 +#define X_GetAtomName 17 +#define X_ChangeProperty 18 +#define X_DeleteProperty 19 +#define X_GetProperty 20 +#define X_ListProperties 21 +#define X_SetSelectionOwner 22 +#define X_GetSelectionOwner 23 +#define X_ConvertSelection 24 +#define X_SendEvent 25 +#define X_GrabPointer 26 +#define X_UngrabPointer 27 +#define X_GrabButton 28 +#define X_UngrabButton 29 +#define X_ChangeActivePointerGrab 30 +#define X_GrabKeyboard 31 +#define X_UngrabKeyboard 32 +#define X_GrabKey 33 +#define X_UngrabKey 34 +#define X_AllowEvents 35 +#define X_GrabServer 36 +#define X_UngrabServer 37 +#define X_QueryPointer 38 +#define X_GetMotionEvents 39 +#define X_TranslateCoords 40 +#define X_WarpPointer 41 +#define X_SetInputFocus 42 +#define X_GetInputFocus 43 +#define X_QueryKeymap 44 +#define X_OpenFont 45 +#define X_CloseFont 46 +#define X_QueryFont 47 +#define X_QueryTextExtents 48 +#define X_ListFonts 49 +#define X_ListFontsWithInfo 50 +#define X_SetFontPath 51 +#define X_GetFontPath 52 +#define X_CreatePixmap 53 +#define X_FreePixmap 54 +#define X_CreateGC 55 +#define X_ChangeGC 56 +#define X_CopyGC 57 +#define X_SetDashes 58 +#define X_SetClipRectangles 59 +#define X_FreeGC 60 +#define X_ClearArea 61 +#define X_CopyArea 62 +#define X_CopyPlane 63 +#define X_PolyPoint 64 +#define X_PolyLine 65 +#define X_PolySegment 66 +#define X_PolyRectangle 67 +#define X_PolyArc 68 +#define X_FillPoly 69 +#define X_PolyFillRectangle 70 +#define X_PolyFillArc 71 +#define X_PutImage 72 +#define X_GetImage 73 +#define X_PolyText8 74 +#define X_PolyText16 75 +#define X_ImageText8 76 +#define X_ImageText16 77 +#define X_CreateColormap 78 +#define X_FreeColormap 79 +#define X_CopyColormapAndFree 80 +#define X_InstallColormap 81 +#define X_UninstallColormap 82 +#define X_ListInstalledColormaps 83 +#define X_AllocColor 84 +#define X_AllocNamedColor 85 +#define X_AllocColorCells 86 +#define X_AllocColorPlanes 87 +#define X_FreeColors 88 +#define X_StoreColors 89 +#define X_StoreNamedColor 90 +#define X_QueryColors 91 +#define X_LookupColor 92 +#define X_CreateCursor 93 +#define X_CreateGlyphCursor 94 +#define X_FreeCursor 95 +#define X_RecolorCursor 96 +#define X_QueryBestSize 97 +#define X_QueryExtension 98 +#define X_ListExtensions 99 +#define X_ChangeKeyboardMapping 100 +#define X_GetKeyboardMapping 101 +#define X_ChangeKeyboardControl 102 +#define X_GetKeyboardControl 103 +#define X_Bell 104 +#define X_ChangePointerControl 105 +#define X_GetPointerControl 106 +#define X_SetScreenSaver 107 +#define X_GetScreenSaver 108 +#define X_ChangeHosts 109 +#define X_ListHosts 110 +#define X_SetAccessControl 111 +#define X_SetCloseDownMode 112 +#define X_KillClient 113 +#define X_RotateProperties 114 +#define X_ForceScreenSaver 115 +#define X_SetPointerMapping 116 +#define X_GetPointerMapping 117 +#define X_SetModifierMapping 118 +#define X_GetModifierMapping 119 +#define X_NoOperation 127 + +/* restore these definitions back to the typedefs in X.h */ +#undef Window +#undef Drawable +#undef Font +#undef Pixmap +#undef Cursor +#undef Colormap +#undef GContext +#undef Atom +#undef VisualID +#undef Time +#undef KeyCode +#undef KeySym + +#endif /* XPROTO_H */ diff --git a/include/X11/Xprotostr.h b/include/X11/Xprotostr.h new file mode 100755 index 0000000..8d213dc --- /dev/null +++ b/include/X11/Xprotostr.h @@ -0,0 +1,79 @@ +/* $XConsortium: Xprotostr.h,v 1.5 94/04/17 20:10:53 rws Exp $ */ +#ifndef XPROTOSTRUCTS_H +#define XPROTOSTRUCTS_H + +/*********************************************************** + +Copyright (c) 1987 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. + + +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 + +/* Used by PolySegment */ + +typedef struct _xSegment { + INT16 x1 B16, y1 B16, x2 B16, y2 B16; +} xSegment; + +/* POINT */ + +typedef struct _xPoint { + INT16 x B16, y B16; +} xPoint; + +typedef struct _xRectangle { + INT16 x B16, y B16; + CARD16 width B16, height B16; +} xRectangle; + +/* ARC */ + +typedef struct _xArc { + INT16 x B16, y B16; + CARD16 width B16, height B16; + INT16 angle1 B16, angle2 B16; +} xArc; + +#endif /* XPROTOSTRUCTS_H */ diff --git a/include/X11/keysym.h b/include/X11/keysym.h new file mode 100755 index 0000000..b034dfe --- /dev/null +++ b/include/X11/keysym.h @@ -0,0 +1,60 @@ +/* $XConsortium: keysym.h,v 1.15 94/04/17 20:10:55 rws Exp $ */ + +/*********************************************************** + +Copyright (c) 1987 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. + + +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. + +******************************************************************/ + +/* default keysyms */ +#define XK_MISCELLANY +#define XK_XKB_KEYS +#define XK_LATIN1 +#define XK_LATIN2 +#define XK_LATIN3 +#define XK_LATIN4 +#define XK_GREEK + +#include diff --git a/include/X11/keysymdef.h b/include/X11/keysymdef.h new file mode 100755 index 0000000..dbb7746 --- /dev/null +++ b/include/X11/keysymdef.h @@ -0,0 +1,1572 @@ +/* $TOG: keysymdef.h /main/25 1997/06/21 10:54:51 kaleb $ */ + +/*********************************************************** +Copyright (c) 1987, 1994 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. + + +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. + +******************************************************************/ + +#define XK_VoidSymbol 0xFFFFFF /* void symbol */ + +#ifdef XK_MISCELLANY +/* + * TTY Functions, cleverly chosen to map to ascii, for convenience of + * programming, but could have been arbitrary (at the cost of lookup + * tables in client code. + */ + +#define XK_BackSpace 0xFF08 /* back space, back char */ +#define XK_Tab 0xFF09 +#define XK_Linefeed 0xFF0A /* Linefeed, LF */ +#define XK_Clear 0xFF0B +#define XK_Return 0xFF0D /* Return, enter */ +#define XK_Pause 0xFF13 /* Pause, hold */ +#define XK_Scroll_Lock 0xFF14 +#define XK_Sys_Req 0xFF15 +#define XK_Escape 0xFF1B +#define XK_Delete 0xFFFF /* Delete, rubout */ + + + +/* International & multi-key character composition */ + +#define XK_Multi_key 0xFF20 /* Multi-key character compose */ +#define XK_SingleCandidate 0xFF3C +#define XK_MultipleCandidate 0xFF3D +#define XK_PreviousCandidate 0xFF3E + +/* Japanese keyboard support */ + +#define XK_Kanji 0xFF21 /* Kanji, Kanji convert */ +#define XK_Muhenkan 0xFF22 /* Cancel Conversion */ +#define XK_Henkan_Mode 0xFF23 /* Start/Stop Conversion */ +#define XK_Henkan 0xFF23 /* Alias for Henkan_Mode */ +#define XK_Romaji 0xFF24 /* to Romaji */ +#define XK_Hiragana 0xFF25 /* to Hiragana */ +#define XK_Katakana 0xFF26 /* to Katakana */ +#define XK_Hiragana_Katakana 0xFF27 /* Hiragana/Katakana toggle */ +#define XK_Zenkaku 0xFF28 /* to Zenkaku */ +#define XK_Hankaku 0xFF29 /* to Hankaku */ +#define XK_Zenkaku_Hankaku 0xFF2A /* Zenkaku/Hankaku toggle */ +#define XK_Touroku 0xFF2B /* Add to Dictionary */ +#define XK_Massyo 0xFF2C /* Delete from Dictionary */ +#define XK_Kana_Lock 0xFF2D /* Kana Lock */ +#define XK_Kana_Shift 0xFF2E /* Kana Shift */ +#define XK_Eisu_Shift 0xFF2F /* Alphanumeric Shift */ +#define XK_Eisu_toggle 0xFF30 /* Alphanumeric toggle */ +#define XK_Zen_Koho 0xFF3D /* Multiple/All Candidate(s) */ +#define XK_Mae_Koho 0xFF3E /* Previous Candidate */ + +/* 0xFF31 thru 0xFF3F are under XK_KOREAN */ + +/* Cursor control & motion */ + +#define XK_Home 0xFF50 +#define XK_Left 0xFF51 /* Move left, left arrow */ +#define XK_Up 0xFF52 /* Move up, up arrow */ +#define XK_Right 0xFF53 /* Move right, right arrow */ +#define XK_Down 0xFF54 /* Move down, down arrow */ +#define XK_Prior 0xFF55 /* Prior, previous */ +#define XK_Page_Up 0xFF55 +#define XK_Next 0xFF56 /* Next */ +#define XK_Page_Down 0xFF56 +#define XK_End 0xFF57 /* EOL */ +#define XK_Begin 0xFF58 /* BOL */ + + +/* Misc Functions */ + +#define XK_Select 0xFF60 /* Select, mark */ +#define XK_Print 0xFF61 +#define XK_Execute 0xFF62 /* Execute, run, do */ +#define XK_Insert 0xFF63 /* Insert, insert here */ +#define XK_Undo 0xFF65 /* Undo, oops */ +#define XK_Redo 0xFF66 /* redo, again */ +#define XK_Menu 0xFF67 +#define XK_Find 0xFF68 /* Find, search */ +#define XK_Cancel 0xFF69 /* Cancel, stop, abort, exit */ +#define XK_Help 0xFF6A /* Help */ +#define XK_Break 0xFF6B +#define XK_Mode_switch 0xFF7E /* Character set switch */ +#define XK_script_switch 0xFF7E /* Alias for mode_switch */ +#define XK_Num_Lock 0xFF7F + +/* Keypad Functions, keypad numbers cleverly chosen to map to ascii */ + +#define XK_KP_Space 0xFF80 /* space */ +#define XK_KP_Tab 0xFF89 +#define XK_KP_Enter 0xFF8D /* enter */ +#define XK_KP_F1 0xFF91 /* PF1, KP_A, ... */ +#define XK_KP_F2 0xFF92 +#define XK_KP_F3 0xFF93 +#define XK_KP_F4 0xFF94 +#define XK_KP_Home 0xFF95 +#define XK_KP_Left 0xFF96 +#define XK_KP_Up 0xFF97 +#define XK_KP_Right 0xFF98 +#define XK_KP_Down 0xFF99 +#define XK_KP_Prior 0xFF9A +#define XK_KP_Page_Up 0xFF9A +#define XK_KP_Next 0xFF9B +#define XK_KP_Page_Down 0xFF9B +#define XK_KP_End 0xFF9C +#define XK_KP_Begin 0xFF9D +#define XK_KP_Insert 0xFF9E +#define XK_KP_Delete 0xFF9F +#define XK_KP_Equal 0xFFBD /* equals */ +#define XK_KP_Multiply 0xFFAA +#define XK_KP_Add 0xFFAB +#define XK_KP_Separator 0xFFAC /* separator, often comma */ +#define XK_KP_Subtract 0xFFAD +#define XK_KP_Decimal 0xFFAE +#define XK_KP_Divide 0xFFAF + +#define XK_KP_0 0xFFB0 +#define XK_KP_1 0xFFB1 +#define XK_KP_2 0xFFB2 +#define XK_KP_3 0xFFB3 +#define XK_KP_4 0xFFB4 +#define XK_KP_5 0xFFB5 +#define XK_KP_6 0xFFB6 +#define XK_KP_7 0xFFB7 +#define XK_KP_8 0xFFB8 +#define XK_KP_9 0xFFB9 + + + +/* + * Auxilliary Functions; note the duplicate definitions for left and right + * function keys; Sun keyboards and a few other manufactures have such + * function key groups on the left and/or right sides of the keyboard. + * We've not found a keyboard with more than 35 function keys total. + */ + +#define XK_F1 0xFFBE +#define XK_F2 0xFFBF +#define XK_F3 0xFFC0 +#define XK_F4 0xFFC1 +#define XK_F5 0xFFC2 +#define XK_F6 0xFFC3 +#define XK_F7 0xFFC4 +#define XK_F8 0xFFC5 +#define XK_F9 0xFFC6 +#define XK_F10 0xFFC7 +#define XK_F11 0xFFC8 +#define XK_L1 0xFFC8 +#define XK_F12 0xFFC9 +#define XK_L2 0xFFC9 +#define XK_F13 0xFFCA +#define XK_L3 0xFFCA +#define XK_F14 0xFFCB +#define XK_L4 0xFFCB +#define XK_F15 0xFFCC +#define XK_L5 0xFFCC +#define XK_F16 0xFFCD +#define XK_L6 0xFFCD +#define XK_F17 0xFFCE +#define XK_L7 0xFFCE +#define XK_F18 0xFFCF +#define XK_L8 0xFFCF +#define XK_F19 0xFFD0 +#define XK_L9 0xFFD0 +#define XK_F20 0xFFD1 +#define XK_L10 0xFFD1 +#define XK_F21 0xFFD2 +#define XK_R1 0xFFD2 +#define XK_F22 0xFFD3 +#define XK_R2 0xFFD3 +#define XK_F23 0xFFD4 +#define XK_R3 0xFFD4 +#define XK_F24 0xFFD5 +#define XK_R4 0xFFD5 +#define XK_F25 0xFFD6 +#define XK_R5 0xFFD6 +#define XK_F26 0xFFD7 +#define XK_R6 0xFFD7 +#define XK_F27 0xFFD8 +#define XK_R7 0xFFD8 +#define XK_F28 0xFFD9 +#define XK_R8 0xFFD9 +#define XK_F29 0xFFDA +#define XK_R9 0xFFDA +#define XK_F30 0xFFDB +#define XK_R10 0xFFDB +#define XK_F31 0xFFDC +#define XK_R11 0xFFDC +#define XK_F32 0xFFDD +#define XK_R12 0xFFDD +#define XK_F33 0xFFDE +#define XK_R13 0xFFDE +#define XK_F34 0xFFDF +#define XK_R14 0xFFDF +#define XK_F35 0xFFE0 +#define XK_R15 0xFFE0 + +/* Modifiers */ + +#define XK_Shift_L 0xFFE1 /* Left shift */ +#define XK_Shift_R 0xFFE2 /* Right shift */ +#define XK_Control_L 0xFFE3 /* Left control */ +#define XK_Control_R 0xFFE4 /* Right control */ +#define XK_Caps_Lock 0xFFE5 /* Caps lock */ +#define XK_Shift_Lock 0xFFE6 /* Shift lock */ + +#define XK_Meta_L 0xFFE7 /* Left meta */ +#define XK_Meta_R 0xFFE8 /* Right meta */ +#define XK_Alt_L 0xFFE9 /* Left alt */ +#define XK_Alt_R 0xFFEA /* Right alt */ +#define XK_Super_L 0xFFEB /* Left super */ +#define XK_Super_R 0xFFEC /* Right super */ +#define XK_Hyper_L 0xFFED /* Left hyper */ +#define XK_Hyper_R 0xFFEE /* Right hyper */ +#endif /* XK_MISCELLANY */ + +/* + * ISO 9995 Function and Modifier Keys + * Byte 3 = 0xFE + */ + +#ifdef XK_XKB_KEYS +#define XK_ISO_Lock 0xFE01 +#define XK_ISO_Level2_Latch 0xFE02 +#define XK_ISO_Level3_Shift 0xFE03 +#define XK_ISO_Level3_Latch 0xFE04 +#define XK_ISO_Level3_Lock 0xFE05 +#define XK_ISO_Group_Shift 0xFF7E /* Alias for mode_switch */ +#define XK_ISO_Group_Latch 0xFE06 +#define XK_ISO_Group_Lock 0xFE07 +#define XK_ISO_Next_Group 0xFE08 +#define XK_ISO_Next_Group_Lock 0xFE09 +#define XK_ISO_Prev_Group 0xFE0A +#define XK_ISO_Prev_Group_Lock 0xFE0B +#define XK_ISO_First_Group 0xFE0C +#define XK_ISO_First_Group_Lock 0xFE0D +#define XK_ISO_Last_Group 0xFE0E +#define XK_ISO_Last_Group_Lock 0xFE0F + +#define XK_ISO_Left_Tab 0xFE20 +#define XK_ISO_Move_Line_Up 0xFE21 +#define XK_ISO_Move_Line_Down 0xFE22 +#define XK_ISO_Partial_Line_Up 0xFE23 +#define XK_ISO_Partial_Line_Down 0xFE24 +#define XK_ISO_Partial_Space_Left 0xFE25 +#define XK_ISO_Partial_Space_Right 0xFE26 +#define XK_ISO_Set_Margin_Left 0xFE27 +#define XK_ISO_Set_Margin_Right 0xFE28 +#define XK_ISO_Release_Margin_Left 0xFE29 +#define XK_ISO_Release_Margin_Right 0xFE2A +#define XK_ISO_Release_Both_Margins 0xFE2B +#define XK_ISO_Fast_Cursor_Left 0xFE2C +#define XK_ISO_Fast_Cursor_Right 0xFE2D +#define XK_ISO_Fast_Cursor_Up 0xFE2E +#define XK_ISO_Fast_Cursor_Down 0xFE2F +#define XK_ISO_Continuous_Underline 0xFE30 +#define XK_ISO_Discontinuous_Underline 0xFE31 +#define XK_ISO_Emphasize 0xFE32 +#define XK_ISO_Center_Object 0xFE33 +#define XK_ISO_Enter 0xFE34 + +#define XK_dead_grave 0xFE50 +#define XK_dead_acute 0xFE51 +#define XK_dead_circumflex 0xFE52 +#define XK_dead_tilde 0xFE53 +#define XK_dead_macron 0xFE54 +#define XK_dead_breve 0xFE55 +#define XK_dead_abovedot 0xFE56 +#define XK_dead_diaeresis 0xFE57 +#define XK_dead_abovering 0xFE58 +#define XK_dead_doubleacute 0xFE59 +#define XK_dead_caron 0xFE5A +#define XK_dead_cedilla 0xFE5B +#define XK_dead_ogonek 0xFE5C +#define XK_dead_iota 0xFE5D +#define XK_dead_voiced_sound 0xFE5E +#define XK_dead_semivoiced_sound 0xFE5F +#define XK_dead_belowdot 0xFE60 + +#define XK_First_Virtual_Screen 0xFED0 +#define XK_Prev_Virtual_Screen 0xFED1 +#define XK_Next_Virtual_Screen 0xFED2 +#define XK_Last_Virtual_Screen 0xFED4 +#define XK_Terminate_Server 0xFED5 + +#define XK_AccessX_Enable 0xFE70 +#define XK_AccessX_Feedback_Enable 0xFE71 +#define XK_RepeatKeys_Enable 0xFE72 +#define XK_SlowKeys_Enable 0xFE73 +#define XK_BounceKeys_Enable 0xFE74 +#define XK_StickyKeys_Enable 0xFE75 +#define XK_MouseKeys_Enable 0xFE76 +#define XK_MouseKeys_Accel_Enable 0xFE77 +#define XK_Overlay1_Enable 0xFE78 +#define XK_Overlay2_Enable 0xFE79 +#define XK_AudibleBell_Enable 0xFE7A + +#define XK_Pointer_Left 0xFEE0 +#define XK_Pointer_Right 0xFEE1 +#define XK_Pointer_Up 0xFEE2 +#define XK_Pointer_Down 0xFEE3 +#define XK_Pointer_UpLeft 0xFEE4 +#define XK_Pointer_UpRight 0xFEE5 +#define XK_Pointer_DownLeft 0xFEE6 +#define XK_Pointer_DownRight 0xFEE7 +#define XK_Pointer_Button_Dflt 0xFEE8 +#define XK_Pointer_Button1 0xFEE9 +#define XK_Pointer_Button2 0xFEEA +#define XK_Pointer_Button3 0xFEEB +#define XK_Pointer_Button4 0xFEEC +#define XK_Pointer_Button5 0xFEED +#define XK_Pointer_DblClick_Dflt 0xFEEE +#define XK_Pointer_DblClick1 0xFEEF +#define XK_Pointer_DblClick2 0xFEF0 +#define XK_Pointer_DblClick3 0xFEF1 +#define XK_Pointer_DblClick4 0xFEF2 +#define XK_Pointer_DblClick5 0xFEF3 +#define XK_Pointer_Drag_Dflt 0xFEF4 +#define XK_Pointer_Drag1 0xFEF5 +#define XK_Pointer_Drag2 0xFEF6 +#define XK_Pointer_Drag3 0xFEF7 +#define XK_Pointer_Drag4 0xFEF8 +#define XK_Pointer_Drag5 0xFEFD + +#define XK_Pointer_EnableKeys 0xFEF9 +#define XK_Pointer_Accelerate 0xFEFA +#define XK_Pointer_DfltBtnNext 0xFEFB +#define XK_Pointer_DfltBtnPrev 0xFEFC + +#endif + +/* + * 3270 Terminal Keys + * Byte 3 = 0xFD + */ + +#ifdef XK_3270 +#define XK_3270_Duplicate 0xFD01 +#define XK_3270_FieldMark 0xFD02 +#define XK_3270_Right2 0xFD03 +#define XK_3270_Left2 0xFD04 +#define XK_3270_BackTab 0xFD05 +#define XK_3270_EraseEOF 0xFD06 +#define XK_3270_EraseInput 0xFD07 +#define XK_3270_Reset 0xFD08 +#define XK_3270_Quit 0xFD09 +#define XK_3270_PA1 0xFD0A +#define XK_3270_PA2 0xFD0B +#define XK_3270_PA3 0xFD0C +#define XK_3270_Test 0xFD0D +#define XK_3270_Attn 0xFD0E +#define XK_3270_CursorBlink 0xFD0F +#define XK_3270_AltCursor 0xFD10 +#define XK_3270_KeyClick 0xFD11 +#define XK_3270_Jump 0xFD12 +#define XK_3270_Ident 0xFD13 +#define XK_3270_Rule 0xFD14 +#define XK_3270_Copy 0xFD15 +#define XK_3270_Play 0xFD16 +#define XK_3270_Setup 0xFD17 +#define XK_3270_Record 0xFD18 +#define XK_3270_ChangeScreen 0xFD19 +#define XK_3270_DeleteWord 0xFD1A +#define XK_3270_ExSelect 0xFD1B +#define XK_3270_CursorSelect 0xFD1C +#define XK_3270_PrintScreen 0xFD1D +#define XK_3270_Enter 0xFD1E +#endif + +/* + * Latin 1 + * Byte 3 = 0 + */ +#ifdef XK_LATIN1 +#define XK_space 0x020 +#define XK_exclam 0x021 +#define XK_quotedbl 0x022 +#define XK_numbersign 0x023 +#define XK_dollar 0x024 +#define XK_percent 0x025 +#define XK_ampersand 0x026 +#define XK_apostrophe 0x027 +#define XK_quoteright 0x027 /* deprecated */ +#define XK_parenleft 0x028 +#define XK_parenright 0x029 +#define XK_asterisk 0x02a +#define XK_plus 0x02b +#define XK_comma 0x02c +#define XK_minus 0x02d +#define XK_period 0x02e +#define XK_slash 0x02f +#define XK_0 0x030 +#define XK_1 0x031 +#define XK_2 0x032 +#define XK_3 0x033 +#define XK_4 0x034 +#define XK_5 0x035 +#define XK_6 0x036 +#define XK_7 0x037 +#define XK_8 0x038 +#define XK_9 0x039 +#define XK_colon 0x03a +#define XK_semicolon 0x03b +#define XK_less 0x03c +#define XK_equal 0x03d +#define XK_greater 0x03e +#define XK_question 0x03f +#define XK_at 0x040 +#define XK_A 0x041 +#define XK_B 0x042 +#define XK_C 0x043 +#define XK_D 0x044 +#define XK_E 0x045 +#define XK_F 0x046 +#define XK_G 0x047 +#define XK_H 0x048 +#define XK_I 0x049 +#define XK_J 0x04a +#define XK_K 0x04b +#define XK_L 0x04c +#define XK_M 0x04d +#define XK_N 0x04e +#define XK_O 0x04f +#define XK_P 0x050 +#define XK_Q 0x051 +#define XK_R 0x052 +#define XK_S 0x053 +#define XK_T 0x054 +#define XK_U 0x055 +#define XK_V 0x056 +#define XK_W 0x057 +#define XK_X 0x058 +#define XK_Y 0x059 +#define XK_Z 0x05a +#define XK_bracketleft 0x05b +#define XK_backslash 0x05c +#define XK_bracketright 0x05d +#define XK_asciicircum 0x05e +#define XK_underscore 0x05f +#define XK_grave 0x060 +#define XK_quoteleft 0x060 /* deprecated */ +#define XK_a 0x061 +#define XK_b 0x062 +#define XK_c 0x063 +#define XK_d 0x064 +#define XK_e 0x065 +#define XK_f 0x066 +#define XK_g 0x067 +#define XK_h 0x068 +#define XK_i 0x069 +#define XK_j 0x06a +#define XK_k 0x06b +#define XK_l 0x06c +#define XK_m 0x06d +#define XK_n 0x06e +#define XK_o 0x06f +#define XK_p 0x070 +#define XK_q 0x071 +#define XK_r 0x072 +#define XK_s 0x073 +#define XK_t 0x074 +#define XK_u 0x075 +#define XK_v 0x076 +#define XK_w 0x077 +#define XK_x 0x078 +#define XK_y 0x079 +#define XK_z 0x07a +#define XK_braceleft 0x07b +#define XK_bar 0x07c +#define XK_braceright 0x07d +#define XK_asciitilde 0x07e + +#define XK_nobreakspace 0x0a0 +#define XK_exclamdown 0x0a1 +#define XK_cent 0x0a2 +#define XK_sterling 0x0a3 +#define XK_currency 0x0a4 +#define XK_yen 0x0a5 +#define XK_brokenbar 0x0a6 +#define XK_section 0x0a7 +#define XK_diaeresis 0x0a8 +#define XK_copyright 0x0a9 +#define XK_ordfeminine 0x0aa +#define XK_guillemotleft 0x0ab /* left angle quotation mark */ +#define XK_notsign 0x0ac +#define XK_hyphen 0x0ad +#define XK_registered 0x0ae +#define XK_macron 0x0af +#define XK_degree 0x0b0 +#define XK_plusminus 0x0b1 +#define XK_twosuperior 0x0b2 +#define XK_threesuperior 0x0b3 +#define XK_acute 0x0b4 +#define XK_mu 0x0b5 +#define XK_paragraph 0x0b6 +#define XK_periodcentered 0x0b7 +#define XK_cedilla 0x0b8 +#define XK_onesuperior 0x0b9 +#define XK_masculine 0x0ba +#define XK_guillemotright 0x0bb /* right angle quotation mark */ +#define XK_onequarter 0x0bc +#define XK_onehalf 0x0bd +#define XK_threequarters 0x0be +#define XK_questiondown 0x0bf +#define XK_Agrave 0x0c0 +#define XK_Aacute 0x0c1 +#define XK_Acircumflex 0x0c2 +#define XK_Atilde 0x0c3 +#define XK_Adiaeresis 0x0c4 +#define XK_Aring 0x0c5 +#define XK_AE 0x0c6 +#define XK_Ccedilla 0x0c7 +#define XK_Egrave 0x0c8 +#define XK_Eacute 0x0c9 +#define XK_Ecircumflex 0x0ca +#define XK_Ediaeresis 0x0cb +#define XK_Igrave 0x0cc +#define XK_Iacute 0x0cd +#define XK_Icircumflex 0x0ce +#define XK_Idiaeresis 0x0cf +#define XK_ETH 0x0d0 +#define XK_Eth 0x0d0 /* deprecated */ +#define XK_Ntilde 0x0d1 +#define XK_Ograve 0x0d2 +#define XK_Oacute 0x0d3 +#define XK_Ocircumflex 0x0d4 +#define XK_Otilde 0x0d5 +#define XK_Odiaeresis 0x0d6 +#define XK_multiply 0x0d7 +#define XK_Ooblique 0x0d8 +#define XK_Ugrave 0x0d9 +#define XK_Uacute 0x0da +#define XK_Ucircumflex 0x0db +#define XK_Udiaeresis 0x0dc +#define XK_Yacute 0x0dd +#define XK_THORN 0x0de +#define XK_Thorn 0x0de /* deprecated */ +#define XK_ssharp 0x0df +#define XK_agrave 0x0e0 +#define XK_aacute 0x0e1 +#define XK_acircumflex 0x0e2 +#define XK_atilde 0x0e3 +#define XK_adiaeresis 0x0e4 +#define XK_aring 0x0e5 +#define XK_ae 0x0e6 +#define XK_ccedilla 0x0e7 +#define XK_egrave 0x0e8 +#define XK_eacute 0x0e9 +#define XK_ecircumflex 0x0ea +#define XK_ediaeresis 0x0eb +#define XK_igrave 0x0ec +#define XK_iacute 0x0ed +#define XK_icircumflex 0x0ee +#define XK_idiaeresis 0x0ef +#define XK_eth 0x0f0 +#define XK_ntilde 0x0f1 +#define XK_ograve 0x0f2 +#define XK_oacute 0x0f3 +#define XK_ocircumflex 0x0f4 +#define XK_otilde 0x0f5 +#define XK_odiaeresis 0x0f6 +#define XK_division 0x0f7 +#define XK_oslash 0x0f8 +#define XK_ugrave 0x0f9 +#define XK_uacute 0x0fa +#define XK_ucircumflex 0x0fb +#define XK_udiaeresis 0x0fc +#define XK_yacute 0x0fd +#define XK_thorn 0x0fe +#define XK_ydiaeresis 0x0ff +#endif /* XK_LATIN1 */ + +/* + * Latin 2 + * Byte 3 = 1 + */ + +#ifdef XK_LATIN2 +#define XK_Aogonek 0x1a1 +#define XK_breve 0x1a2 +#define XK_Lstroke 0x1a3 +#define XK_Lcaron 0x1a5 +#define XK_Sacute 0x1a6 +#define XK_Scaron 0x1a9 +#define XK_Scedilla 0x1aa +#define XK_Tcaron 0x1ab +#define XK_Zacute 0x1ac +#define XK_Zcaron 0x1ae +#define XK_Zabovedot 0x1af +#define XK_aogonek 0x1b1 +#define XK_ogonek 0x1b2 +#define XK_lstroke 0x1b3 +#define XK_lcaron 0x1b5 +#define XK_sacute 0x1b6 +#define XK_caron 0x1b7 +#define XK_scaron 0x1b9 +#define XK_scedilla 0x1ba +#define XK_tcaron 0x1bb +#define XK_zacute 0x1bc +#define XK_doubleacute 0x1bd +#define XK_zcaron 0x1be +#define XK_zabovedot 0x1bf +#define XK_Racute 0x1c0 +#define XK_Abreve 0x1c3 +#define XK_Lacute 0x1c5 +#define XK_Cacute 0x1c6 +#define XK_Ccaron 0x1c8 +#define XK_Eogonek 0x1ca +#define XK_Ecaron 0x1cc +#define XK_Dcaron 0x1cf +#define XK_Dstroke 0x1d0 +#define XK_Nacute 0x1d1 +#define XK_Ncaron 0x1d2 +#define XK_Odoubleacute 0x1d5 +#define XK_Rcaron 0x1d8 +#define XK_Uring 0x1d9 +#define XK_Udoubleacute 0x1db +#define XK_Tcedilla 0x1de +#define XK_racute 0x1e0 +#define XK_abreve 0x1e3 +#define XK_lacute 0x1e5 +#define XK_cacute 0x1e6 +#define XK_ccaron 0x1e8 +#define XK_eogonek 0x1ea +#define XK_ecaron 0x1ec +#define XK_dcaron 0x1ef +#define XK_dstroke 0x1f0 +#define XK_nacute 0x1f1 +#define XK_ncaron 0x1f2 +#define XK_odoubleacute 0x1f5 +#define XK_udoubleacute 0x1fb +#define XK_rcaron 0x1f8 +#define XK_uring 0x1f9 +#define XK_tcedilla 0x1fe +#define XK_abovedot 0x1ff +#endif /* XK_LATIN2 */ + +/* + * Latin 3 + * Byte 3 = 2 + */ + +#ifdef XK_LATIN3 +#define XK_Hstroke 0x2a1 +#define XK_Hcircumflex 0x2a6 +#define XK_Iabovedot 0x2a9 +#define XK_Gbreve 0x2ab +#define XK_Jcircumflex 0x2ac +#define XK_hstroke 0x2b1 +#define XK_hcircumflex 0x2b6 +#define XK_idotless 0x2b9 +#define XK_gbreve 0x2bb +#define XK_jcircumflex 0x2bc +#define XK_Cabovedot 0x2c5 +#define XK_Ccircumflex 0x2c6 +#define XK_Gabovedot 0x2d5 +#define XK_Gcircumflex 0x2d8 +#define XK_Ubreve 0x2dd +#define XK_Scircumflex 0x2de +#define XK_cabovedot 0x2e5 +#define XK_ccircumflex 0x2e6 +#define XK_gabovedot 0x2f5 +#define XK_gcircumflex 0x2f8 +#define XK_ubreve 0x2fd +#define XK_scircumflex 0x2fe +#endif /* XK_LATIN3 */ + + +/* + * Latin 4 + * Byte 3 = 3 + */ + +#ifdef XK_LATIN4 +#define XK_kra 0x3a2 +#define XK_kappa 0x3a2 /* deprecated */ +#define XK_Rcedilla 0x3a3 +#define XK_Itilde 0x3a5 +#define XK_Lcedilla 0x3a6 +#define XK_Emacron 0x3aa +#define XK_Gcedilla 0x3ab +#define XK_Tslash 0x3ac +#define XK_rcedilla 0x3b3 +#define XK_itilde 0x3b5 +#define XK_lcedilla 0x3b6 +#define XK_emacron 0x3ba +#define XK_gcedilla 0x3bb +#define XK_tslash 0x3bc +#define XK_ENG 0x3bd +#define XK_eng 0x3bf +#define XK_Amacron 0x3c0 +#define XK_Iogonek 0x3c7 +#define XK_Eabovedot 0x3cc +#define XK_Imacron 0x3cf +#define XK_Ncedilla 0x3d1 +#define XK_Omacron 0x3d2 +#define XK_Kcedilla 0x3d3 +#define XK_Uogonek 0x3d9 +#define XK_Utilde 0x3dd +#define XK_Umacron 0x3de +#define XK_amacron 0x3e0 +#define XK_iogonek 0x3e7 +#define XK_eabovedot 0x3ec +#define XK_imacron 0x3ef +#define XK_ncedilla 0x3f1 +#define XK_omacron 0x3f2 +#define XK_kcedilla 0x3f3 +#define XK_uogonek 0x3f9 +#define XK_utilde 0x3fd +#define XK_umacron 0x3fe +#endif /* XK_LATIN4 */ + +/* + * Katakana + * Byte 3 = 4 + */ + +#ifdef XK_KATAKANA +#define XK_overline 0x47e +#define XK_kana_fullstop 0x4a1 +#define XK_kana_openingbracket 0x4a2 +#define XK_kana_closingbracket 0x4a3 +#define XK_kana_comma 0x4a4 +#define XK_kana_conjunctive 0x4a5 +#define XK_kana_middledot 0x4a5 /* deprecated */ +#define XK_kana_WO 0x4a6 +#define XK_kana_a 0x4a7 +#define XK_kana_i 0x4a8 +#define XK_kana_u 0x4a9 +#define XK_kana_e 0x4aa +#define XK_kana_o 0x4ab +#define XK_kana_ya 0x4ac +#define XK_kana_yu 0x4ad +#define XK_kana_yo 0x4ae +#define XK_kana_tsu 0x4af +#define XK_kana_tu 0x4af /* deprecated */ +#define XK_prolongedsound 0x4b0 +#define XK_kana_A 0x4b1 +#define XK_kana_I 0x4b2 +#define XK_kana_U 0x4b3 +#define XK_kana_E 0x4b4 +#define XK_kana_O 0x4b5 +#define XK_kana_KA 0x4b6 +#define XK_kana_KI 0x4b7 +#define XK_kana_KU 0x4b8 +#define XK_kana_KE 0x4b9 +#define XK_kana_KO 0x4ba +#define XK_kana_SA 0x4bb +#define XK_kana_SHI 0x4bc +#define XK_kana_SU 0x4bd +#define XK_kana_SE 0x4be +#define XK_kana_SO 0x4bf +#define XK_kana_TA 0x4c0 +#define XK_kana_CHI 0x4c1 +#define XK_kana_TI 0x4c1 /* deprecated */ +#define XK_kana_TSU 0x4c2 +#define XK_kana_TU 0x4c2 /* deprecated */ +#define XK_kana_TE 0x4c3 +#define XK_kana_TO 0x4c4 +#define XK_kana_NA 0x4c5 +#define XK_kana_NI 0x4c6 +#define XK_kana_NU 0x4c7 +#define XK_kana_NE 0x4c8 +#define XK_kana_NO 0x4c9 +#define XK_kana_HA 0x4ca +#define XK_kana_HI 0x4cb +#define XK_kana_FU 0x4cc +#define XK_kana_HU 0x4cc /* deprecated */ +#define XK_kana_HE 0x4cd +#define XK_kana_HO 0x4ce +#define XK_kana_MA 0x4cf +#define XK_kana_MI 0x4d0 +#define XK_kana_MU 0x4d1 +#define XK_kana_ME 0x4d2 +#define XK_kana_MO 0x4d3 +#define XK_kana_YA 0x4d4 +#define XK_kana_YU 0x4d5 +#define XK_kana_YO 0x4d6 +#define XK_kana_RA 0x4d7 +#define XK_kana_RI 0x4d8 +#define XK_kana_RU 0x4d9 +#define XK_kana_RE 0x4da +#define XK_kana_RO 0x4db +#define XK_kana_WA 0x4dc +#define XK_kana_N 0x4dd +#define XK_voicedsound 0x4de +#define XK_semivoicedsound 0x4df +#define XK_kana_switch 0xFF7E /* Alias for mode_switch */ +#endif /* XK_KATAKANA */ + +/* + * Arabic + * Byte 3 = 5 + */ + +#ifdef XK_ARABIC +#define XK_Arabic_comma 0x5ac +#define XK_Arabic_semicolon 0x5bb +#define XK_Arabic_question_mark 0x5bf +#define XK_Arabic_hamza 0x5c1 +#define XK_Arabic_maddaonalef 0x5c2 +#define XK_Arabic_hamzaonalef 0x5c3 +#define XK_Arabic_hamzaonwaw 0x5c4 +#define XK_Arabic_hamzaunderalef 0x5c5 +#define XK_Arabic_hamzaonyeh 0x5c6 +#define XK_Arabic_alef 0x5c7 +#define XK_Arabic_beh 0x5c8 +#define XK_Arabic_tehmarbuta 0x5c9 +#define XK_Arabic_teh 0x5ca +#define XK_Arabic_theh 0x5cb +#define XK_Arabic_jeem 0x5cc +#define XK_Arabic_hah 0x5cd +#define XK_Arabic_khah 0x5ce +#define XK_Arabic_dal 0x5cf +#define XK_Arabic_thal 0x5d0 +#define XK_Arabic_ra 0x5d1 +#define XK_Arabic_zain 0x5d2 +#define XK_Arabic_seen 0x5d3 +#define XK_Arabic_sheen 0x5d4 +#define XK_Arabic_sad 0x5d5 +#define XK_Arabic_dad 0x5d6 +#define XK_Arabic_tah 0x5d7 +#define XK_Arabic_zah 0x5d8 +#define XK_Arabic_ain 0x5d9 +#define XK_Arabic_ghain 0x5da +#define XK_Arabic_tatweel 0x5e0 +#define XK_Arabic_feh 0x5e1 +#define XK_Arabic_qaf 0x5e2 +#define XK_Arabic_kaf 0x5e3 +#define XK_Arabic_lam 0x5e4 +#define XK_Arabic_meem 0x5e5 +#define XK_Arabic_noon 0x5e6 +#define XK_Arabic_ha 0x5e7 +#define XK_Arabic_heh 0x5e7 /* deprecated */ +#define XK_Arabic_waw 0x5e8 +#define XK_Arabic_alefmaksura 0x5e9 +#define XK_Arabic_yeh 0x5ea +#define XK_Arabic_fathatan 0x5eb +#define XK_Arabic_dammatan 0x5ec +#define XK_Arabic_kasratan 0x5ed +#define XK_Arabic_fatha 0x5ee +#define XK_Arabic_damma 0x5ef +#define XK_Arabic_kasra 0x5f0 +#define XK_Arabic_shadda 0x5f1 +#define XK_Arabic_sukun 0x5f2 +#define XK_Arabic_switch 0xFF7E /* Alias for mode_switch */ +#endif /* XK_ARABIC */ + +/* + * Cyrillic + * Byte 3 = 6 + */ +#ifdef XK_CYRILLIC +#define XK_Serbian_dje 0x6a1 +#define XK_Macedonia_gje 0x6a2 +#define XK_Cyrillic_io 0x6a3 +#define XK_Ukrainian_ie 0x6a4 +#define XK_Ukranian_je 0x6a4 /* deprecated */ +#define XK_Macedonia_dse 0x6a5 +#define XK_Ukrainian_i 0x6a6 +#define XK_Ukranian_i 0x6a6 /* deprecated */ +#define XK_Ukrainian_yi 0x6a7 +#define XK_Ukranian_yi 0x6a7 /* deprecated */ +#define XK_Cyrillic_je 0x6a8 +#define XK_Serbian_je 0x6a8 /* deprecated */ +#define XK_Cyrillic_lje 0x6a9 +#define XK_Serbian_lje 0x6a9 /* deprecated */ +#define XK_Cyrillic_nje 0x6aa +#define XK_Serbian_nje 0x6aa /* deprecated */ +#define XK_Serbian_tshe 0x6ab +#define XK_Macedonia_kje 0x6ac +#define XK_Byelorussian_shortu 0x6ae +#define XK_Cyrillic_dzhe 0x6af +#define XK_Serbian_dze 0x6af /* deprecated */ +#define XK_numerosign 0x6b0 +#define XK_Serbian_DJE 0x6b1 +#define XK_Macedonia_GJE 0x6b2 +#define XK_Cyrillic_IO 0x6b3 +#define XK_Ukrainian_IE 0x6b4 +#define XK_Ukranian_JE 0x6b4 /* deprecated */ +#define XK_Macedonia_DSE 0x6b5 +#define XK_Ukrainian_I 0x6b6 +#define XK_Ukranian_I 0x6b6 /* deprecated */ +#define XK_Ukrainian_YI 0x6b7 +#define XK_Ukranian_YI 0x6b7 /* deprecated */ +#define XK_Cyrillic_JE 0x6b8 +#define XK_Serbian_JE 0x6b8 /* deprecated */ +#define XK_Cyrillic_LJE 0x6b9 +#define XK_Serbian_LJE 0x6b9 /* deprecated */ +#define XK_Cyrillic_NJE 0x6ba +#define XK_Serbian_NJE 0x6ba /* deprecated */ +#define XK_Serbian_TSHE 0x6bb +#define XK_Macedonia_KJE 0x6bc +#define XK_Byelorussian_SHORTU 0x6be +#define XK_Cyrillic_DZHE 0x6bf +#define XK_Serbian_DZE 0x6bf /* deprecated */ +#define XK_Cyrillic_yu 0x6c0 +#define XK_Cyrillic_a 0x6c1 +#define XK_Cyrillic_be 0x6c2 +#define XK_Cyrillic_tse 0x6c3 +#define XK_Cyrillic_de 0x6c4 +#define XK_Cyrillic_ie 0x6c5 +#define XK_Cyrillic_ef 0x6c6 +#define XK_Cyrillic_ghe 0x6c7 +#define XK_Cyrillic_ha 0x6c8 +#define XK_Cyrillic_i 0x6c9 +#define XK_Cyrillic_shorti 0x6ca +#define XK_Cyrillic_ka 0x6cb +#define XK_Cyrillic_el 0x6cc +#define XK_Cyrillic_em 0x6cd +#define XK_Cyrillic_en 0x6ce +#define XK_Cyrillic_o 0x6cf +#define XK_Cyrillic_pe 0x6d0 +#define XK_Cyrillic_ya 0x6d1 +#define XK_Cyrillic_er 0x6d2 +#define XK_Cyrillic_es 0x6d3 +#define XK_Cyrillic_te 0x6d4 +#define XK_Cyrillic_u 0x6d5 +#define XK_Cyrillic_zhe 0x6d6 +#define XK_Cyrillic_ve 0x6d7 +#define XK_Cyrillic_softsign 0x6d8 +#define XK_Cyrillic_yeru 0x6d9 +#define XK_Cyrillic_ze 0x6da +#define XK_Cyrillic_sha 0x6db +#define XK_Cyrillic_e 0x6dc +#define XK_Cyrillic_shcha 0x6dd +#define XK_Cyrillic_che 0x6de +#define XK_Cyrillic_hardsign 0x6df +#define XK_Cyrillic_YU 0x6e0 +#define XK_Cyrillic_A 0x6e1 +#define XK_Cyrillic_BE 0x6e2 +#define XK_Cyrillic_TSE 0x6e3 +#define XK_Cyrillic_DE 0x6e4 +#define XK_Cyrillic_IE 0x6e5 +#define XK_Cyrillic_EF 0x6e6 +#define XK_Cyrillic_GHE 0x6e7 +#define XK_Cyrillic_HA 0x6e8 +#define XK_Cyrillic_I 0x6e9 +#define XK_Cyrillic_SHORTI 0x6ea +#define XK_Cyrillic_KA 0x6eb +#define XK_Cyrillic_EL 0x6ec +#define XK_Cyrillic_EM 0x6ed +#define XK_Cyrillic_EN 0x6ee +#define XK_Cyrillic_O 0x6ef +#define XK_Cyrillic_PE 0x6f0 +#define XK_Cyrillic_YA 0x6f1 +#define XK_Cyrillic_ER 0x6f2 +#define XK_Cyrillic_ES 0x6f3 +#define XK_Cyrillic_TE 0x6f4 +#define XK_Cyrillic_U 0x6f5 +#define XK_Cyrillic_ZHE 0x6f6 +#define XK_Cyrillic_VE 0x6f7 +#define XK_Cyrillic_SOFTSIGN 0x6f8 +#define XK_Cyrillic_YERU 0x6f9 +#define XK_Cyrillic_ZE 0x6fa +#define XK_Cyrillic_SHA 0x6fb +#define XK_Cyrillic_E 0x6fc +#define XK_Cyrillic_SHCHA 0x6fd +#define XK_Cyrillic_CHE 0x6fe +#define XK_Cyrillic_HARDSIGN 0x6ff +#endif /* XK_CYRILLIC */ + +/* + * Greek + * Byte 3 = 7 + */ + +#ifdef XK_GREEK +#define XK_Greek_ALPHAaccent 0x7a1 +#define XK_Greek_EPSILONaccent 0x7a2 +#define XK_Greek_ETAaccent 0x7a3 +#define XK_Greek_IOTAaccent 0x7a4 +#define XK_Greek_IOTAdiaeresis 0x7a5 +#define XK_Greek_OMICRONaccent 0x7a7 +#define XK_Greek_UPSILONaccent 0x7a8 +#define XK_Greek_UPSILONdieresis 0x7a9 +#define XK_Greek_OMEGAaccent 0x7ab +#define XK_Greek_accentdieresis 0x7ae +#define XK_Greek_horizbar 0x7af +#define XK_Greek_alphaaccent 0x7b1 +#define XK_Greek_epsilonaccent 0x7b2 +#define XK_Greek_etaaccent 0x7b3 +#define XK_Greek_iotaaccent 0x7b4 +#define XK_Greek_iotadieresis 0x7b5 +#define XK_Greek_iotaaccentdieresis 0x7b6 +#define XK_Greek_omicronaccent 0x7b7 +#define XK_Greek_upsilonaccent 0x7b8 +#define XK_Greek_upsilondieresis 0x7b9 +#define XK_Greek_upsilonaccentdieresis 0x7ba +#define XK_Greek_omegaaccent 0x7bb +#define XK_Greek_ALPHA 0x7c1 +#define XK_Greek_BETA 0x7c2 +#define XK_Greek_GAMMA 0x7c3 +#define XK_Greek_DELTA 0x7c4 +#define XK_Greek_EPSILON 0x7c5 +#define XK_Greek_ZETA 0x7c6 +#define XK_Greek_ETA 0x7c7 +#define XK_Greek_THETA 0x7c8 +#define XK_Greek_IOTA 0x7c9 +#define XK_Greek_KAPPA 0x7ca +#define XK_Greek_LAMDA 0x7cb +#define XK_Greek_LAMBDA 0x7cb +#define XK_Greek_MU 0x7cc +#define XK_Greek_NU 0x7cd +#define XK_Greek_XI 0x7ce +#define XK_Greek_OMICRON 0x7cf +#define XK_Greek_PI 0x7d0 +#define XK_Greek_RHO 0x7d1 +#define XK_Greek_SIGMA 0x7d2 +#define XK_Greek_TAU 0x7d4 +#define XK_Greek_UPSILON 0x7d5 +#define XK_Greek_PHI 0x7d6 +#define XK_Greek_CHI 0x7d7 +#define XK_Greek_PSI 0x7d8 +#define XK_Greek_OMEGA 0x7d9 +#define XK_Greek_alpha 0x7e1 +#define XK_Greek_beta 0x7e2 +#define XK_Greek_gamma 0x7e3 +#define XK_Greek_delta 0x7e4 +#define XK_Greek_epsilon 0x7e5 +#define XK_Greek_zeta 0x7e6 +#define XK_Greek_eta 0x7e7 +#define XK_Greek_theta 0x7e8 +#define XK_Greek_iota 0x7e9 +#define XK_Greek_kappa 0x7ea +#define XK_Greek_lamda 0x7eb +#define XK_Greek_lambda 0x7eb +#define XK_Greek_mu 0x7ec +#define XK_Greek_nu 0x7ed +#define XK_Greek_xi 0x7ee +#define XK_Greek_omicron 0x7ef +#define XK_Greek_pi 0x7f0 +#define XK_Greek_rho 0x7f1 +#define XK_Greek_sigma 0x7f2 +#define XK_Greek_finalsmallsigma 0x7f3 +#define XK_Greek_tau 0x7f4 +#define XK_Greek_upsilon 0x7f5 +#define XK_Greek_phi 0x7f6 +#define XK_Greek_chi 0x7f7 +#define XK_Greek_psi 0x7f8 +#define XK_Greek_omega 0x7f9 +#define XK_Greek_switch 0xFF7E /* Alias for mode_switch */ +#endif /* XK_GREEK */ + +/* + * Technical + * Byte 3 = 8 + */ + +#ifdef XK_TECHNICAL +#define XK_leftradical 0x8a1 +#define XK_topleftradical 0x8a2 +#define XK_horizconnector 0x8a3 +#define XK_topintegral 0x8a4 +#define XK_botintegral 0x8a5 +#define XK_vertconnector 0x8a6 +#define XK_topleftsqbracket 0x8a7 +#define XK_botleftsqbracket 0x8a8 +#define XK_toprightsqbracket 0x8a9 +#define XK_botrightsqbracket 0x8aa +#define XK_topleftparens 0x8ab +#define XK_botleftparens 0x8ac +#define XK_toprightparens 0x8ad +#define XK_botrightparens 0x8ae +#define XK_leftmiddlecurlybrace 0x8af +#define XK_rightmiddlecurlybrace 0x8b0 +#define XK_topleftsummation 0x8b1 +#define XK_botleftsummation 0x8b2 +#define XK_topvertsummationconnector 0x8b3 +#define XK_botvertsummationconnector 0x8b4 +#define XK_toprightsummation 0x8b5 +#define XK_botrightsummation 0x8b6 +#define XK_rightmiddlesummation 0x8b7 +#define XK_lessthanequal 0x8bc +#define XK_notequal 0x8bd +#define XK_greaterthanequal 0x8be +#define XK_integral 0x8bf +#define XK_therefore 0x8c0 +#define XK_variation 0x8c1 +#define XK_infinity 0x8c2 +#define XK_nabla 0x8c5 +#define XK_approximate 0x8c8 +#define XK_similarequal 0x8c9 +#define XK_ifonlyif 0x8cd +#define XK_implies 0x8ce +#define XK_identical 0x8cf +#define XK_radical 0x8d6 +#define XK_includedin 0x8da +#define XK_includes 0x8db +#define XK_intersection 0x8dc +#define XK_union 0x8dd +#define XK_logicaland 0x8de +#define XK_logicalor 0x8df +#define XK_partialderivative 0x8ef +#define XK_function 0x8f6 +#define XK_leftarrow 0x8fb +#define XK_uparrow 0x8fc +#define XK_rightarrow 0x8fd +#define XK_downarrow 0x8fe +#endif /* XK_TECHNICAL */ + +/* + * Special + * Byte 3 = 9 + */ + +#ifdef XK_SPECIAL +#define XK_blank 0x9df +#define XK_soliddiamond 0x9e0 +#define XK_checkerboard 0x9e1 +#define XK_ht 0x9e2 +#define XK_ff 0x9e3 +#define XK_cr 0x9e4 +#define XK_lf 0x9e5 +#define XK_nl 0x9e8 +#define XK_vt 0x9e9 +#define XK_lowrightcorner 0x9ea +#define XK_uprightcorner 0x9eb +#define XK_upleftcorner 0x9ec +#define XK_lowleftcorner 0x9ed +#define XK_crossinglines 0x9ee +#define XK_horizlinescan1 0x9ef +#define XK_horizlinescan3 0x9f0 +#define XK_horizlinescan5 0x9f1 +#define XK_horizlinescan7 0x9f2 +#define XK_horizlinescan9 0x9f3 +#define XK_leftt 0x9f4 +#define XK_rightt 0x9f5 +#define XK_bott 0x9f6 +#define XK_topt 0x9f7 +#define XK_vertbar 0x9f8 +#endif /* XK_SPECIAL */ + +/* + * Publishing + * Byte 3 = a + */ + +#ifdef XK_PUBLISHING +#define XK_emspace 0xaa1 +#define XK_enspace 0xaa2 +#define XK_em3space 0xaa3 +#define XK_em4space 0xaa4 +#define XK_digitspace 0xaa5 +#define XK_punctspace 0xaa6 +#define XK_thinspace 0xaa7 +#define XK_hairspace 0xaa8 +#define XK_emdash 0xaa9 +#define XK_endash 0xaaa +#define XK_signifblank 0xaac +#define XK_ellipsis 0xaae +#define XK_doubbaselinedot 0xaaf +#define XK_onethird 0xab0 +#define XK_twothirds 0xab1 +#define XK_onefifth 0xab2 +#define XK_twofifths 0xab3 +#define XK_threefifths 0xab4 +#define XK_fourfifths 0xab5 +#define XK_onesixth 0xab6 +#define XK_fivesixths 0xab7 +#define XK_careof 0xab8 +#define XK_figdash 0xabb +#define XK_leftanglebracket 0xabc +#define XK_decimalpoint 0xabd +#define XK_rightanglebracket 0xabe +#define XK_marker 0xabf +#define XK_oneeighth 0xac3 +#define XK_threeeighths 0xac4 +#define XK_fiveeighths 0xac5 +#define XK_seveneighths 0xac6 +#define XK_trademark 0xac9 +#define XK_signaturemark 0xaca +#define XK_trademarkincircle 0xacb +#define XK_leftopentriangle 0xacc +#define XK_rightopentriangle 0xacd +#define XK_emopencircle 0xace +#define XK_emopenrectangle 0xacf +#define XK_leftsinglequotemark 0xad0 +#define XK_rightsinglequotemark 0xad1 +#define XK_leftdoublequotemark 0xad2 +#define XK_rightdoublequotemark 0xad3 +#define XK_prescription 0xad4 +#define XK_minutes 0xad6 +#define XK_seconds 0xad7 +#define XK_latincross 0xad9 +#define XK_hexagram 0xada +#define XK_filledrectbullet 0xadb +#define XK_filledlefttribullet 0xadc +#define XK_filledrighttribullet 0xadd +#define XK_emfilledcircle 0xade +#define XK_emfilledrect 0xadf +#define XK_enopencircbullet 0xae0 +#define XK_enopensquarebullet 0xae1 +#define XK_openrectbullet 0xae2 +#define XK_opentribulletup 0xae3 +#define XK_opentribulletdown 0xae4 +#define XK_openstar 0xae5 +#define XK_enfilledcircbullet 0xae6 +#define XK_enfilledsqbullet 0xae7 +#define XK_filledtribulletup 0xae8 +#define XK_filledtribulletdown 0xae9 +#define XK_leftpointer 0xaea +#define XK_rightpointer 0xaeb +#define XK_club 0xaec +#define XK_diamond 0xaed +#define XK_heart 0xaee +#define XK_maltesecross 0xaf0 +#define XK_dagger 0xaf1 +#define XK_doubledagger 0xaf2 +#define XK_checkmark 0xaf3 +#define XK_ballotcross 0xaf4 +#define XK_musicalsharp 0xaf5 +#define XK_musicalflat 0xaf6 +#define XK_malesymbol 0xaf7 +#define XK_femalesymbol 0xaf8 +#define XK_telephone 0xaf9 +#define XK_telephonerecorder 0xafa +#define XK_phonographcopyright 0xafb +#define XK_caret 0xafc +#define XK_singlelowquotemark 0xafd +#define XK_doublelowquotemark 0xafe +#define XK_cursor 0xaff +#endif /* XK_PUBLISHING */ + +/* + * APL + * Byte 3 = b + */ + +#ifdef XK_APL +#define XK_leftcaret 0xba3 +#define XK_rightcaret 0xba6 +#define XK_downcaret 0xba8 +#define XK_upcaret 0xba9 +#define XK_overbar 0xbc0 +#define XK_downtack 0xbc2 +#define XK_upshoe 0xbc3 +#define XK_downstile 0xbc4 +#define XK_underbar 0xbc6 +#define XK_jot 0xbca +#define XK_quad 0xbcc +#define XK_uptack 0xbce +#define XK_circle 0xbcf +#define XK_upstile 0xbd3 +#define XK_downshoe 0xbd6 +#define XK_rightshoe 0xbd8 +#define XK_leftshoe 0xbda +#define XK_lefttack 0xbdc +#define XK_righttack 0xbfc +#endif /* XK_APL */ + +/* + * Hebrew + * Byte 3 = c + */ + +#ifdef XK_HEBREW +#define XK_hebrew_doublelowline 0xcdf +#define XK_hebrew_aleph 0xce0 +#define XK_hebrew_bet 0xce1 +#define XK_hebrew_beth 0xce1 /* deprecated */ +#define XK_hebrew_gimel 0xce2 +#define XK_hebrew_gimmel 0xce2 /* deprecated */ +#define XK_hebrew_dalet 0xce3 +#define XK_hebrew_daleth 0xce3 /* deprecated */ +#define XK_hebrew_he 0xce4 +#define XK_hebrew_waw 0xce5 +#define XK_hebrew_zain 0xce6 +#define XK_hebrew_zayin 0xce6 /* deprecated */ +#define XK_hebrew_chet 0xce7 +#define XK_hebrew_het 0xce7 /* deprecated */ +#define XK_hebrew_tet 0xce8 +#define XK_hebrew_teth 0xce8 /* deprecated */ +#define XK_hebrew_yod 0xce9 +#define XK_hebrew_finalkaph 0xcea +#define XK_hebrew_kaph 0xceb +#define XK_hebrew_lamed 0xcec +#define XK_hebrew_finalmem 0xced +#define XK_hebrew_mem 0xcee +#define XK_hebrew_finalnun 0xcef +#define XK_hebrew_nun 0xcf0 +#define XK_hebrew_samech 0xcf1 +#define XK_hebrew_samekh 0xcf1 /* deprecated */ +#define XK_hebrew_ayin 0xcf2 +#define XK_hebrew_finalpe 0xcf3 +#define XK_hebrew_pe 0xcf4 +#define XK_hebrew_finalzade 0xcf5 +#define XK_hebrew_finalzadi 0xcf5 /* deprecated */ +#define XK_hebrew_zade 0xcf6 +#define XK_hebrew_zadi 0xcf6 /* deprecated */ +#define XK_hebrew_qoph 0xcf7 +#define XK_hebrew_kuf 0xcf7 /* deprecated */ +#define XK_hebrew_resh 0xcf8 +#define XK_hebrew_shin 0xcf9 +#define XK_hebrew_taw 0xcfa +#define XK_hebrew_taf 0xcfa /* deprecated */ +#define XK_Hebrew_switch 0xFF7E /* Alias for mode_switch */ +#endif /* XK_HEBREW */ + +/* + * Thai + * Byte 3 = d + */ + +#ifdef XK_THAI +#define XK_Thai_kokai 0xda1 +#define XK_Thai_khokhai 0xda2 +#define XK_Thai_khokhuat 0xda3 +#define XK_Thai_khokhwai 0xda4 +#define XK_Thai_khokhon 0xda5 +#define XK_Thai_khorakhang 0xda6 +#define XK_Thai_ngongu 0xda7 +#define XK_Thai_chochan 0xda8 +#define XK_Thai_choching 0xda9 +#define XK_Thai_chochang 0xdaa +#define XK_Thai_soso 0xdab +#define XK_Thai_chochoe 0xdac +#define XK_Thai_yoying 0xdad +#define XK_Thai_dochada 0xdae +#define XK_Thai_topatak 0xdaf +#define XK_Thai_thothan 0xdb0 +#define XK_Thai_thonangmontho 0xdb1 +#define XK_Thai_thophuthao 0xdb2 +#define XK_Thai_nonen 0xdb3 +#define XK_Thai_dodek 0xdb4 +#define XK_Thai_totao 0xdb5 +#define XK_Thai_thothung 0xdb6 +#define XK_Thai_thothahan 0xdb7 +#define XK_Thai_thothong 0xdb8 +#define XK_Thai_nonu 0xdb9 +#define XK_Thai_bobaimai 0xdba +#define XK_Thai_popla 0xdbb +#define XK_Thai_phophung 0xdbc +#define XK_Thai_fofa 0xdbd +#define XK_Thai_phophan 0xdbe +#define XK_Thai_fofan 0xdbf +#define XK_Thai_phosamphao 0xdc0 +#define XK_Thai_moma 0xdc1 +#define XK_Thai_yoyak 0xdc2 +#define XK_Thai_rorua 0xdc3 +#define XK_Thai_ru 0xdc4 +#define XK_Thai_loling 0xdc5 +#define XK_Thai_lu 0xdc6 +#define XK_Thai_wowaen 0xdc7 +#define XK_Thai_sosala 0xdc8 +#define XK_Thai_sorusi 0xdc9 +#define XK_Thai_sosua 0xdca +#define XK_Thai_hohip 0xdcb +#define XK_Thai_lochula 0xdcc +#define XK_Thai_oang 0xdcd +#define XK_Thai_honokhuk 0xdce +#define XK_Thai_paiyannoi 0xdcf +#define XK_Thai_saraa 0xdd0 +#define XK_Thai_maihanakat 0xdd1 +#define XK_Thai_saraaa 0xdd2 +#define XK_Thai_saraam 0xdd3 +#define XK_Thai_sarai 0xdd4 +#define XK_Thai_saraii 0xdd5 +#define XK_Thai_saraue 0xdd6 +#define XK_Thai_sarauee 0xdd7 +#define XK_Thai_sarau 0xdd8 +#define XK_Thai_sarauu 0xdd9 +#define XK_Thai_phinthu 0xdda +#define XK_Thai_maihanakat_maitho 0xdde +#define XK_Thai_baht 0xddf +#define XK_Thai_sarae 0xde0 +#define XK_Thai_saraae 0xde1 +#define XK_Thai_sarao 0xde2 +#define XK_Thai_saraaimaimuan 0xde3 +#define XK_Thai_saraaimaimalai 0xde4 +#define XK_Thai_lakkhangyao 0xde5 +#define XK_Thai_maiyamok 0xde6 +#define XK_Thai_maitaikhu 0xde7 +#define XK_Thai_maiek 0xde8 +#define XK_Thai_maitho 0xde9 +#define XK_Thai_maitri 0xdea +#define XK_Thai_maichattawa 0xdeb +#define XK_Thai_thanthakhat 0xdec +#define XK_Thai_nikhahit 0xded +#define XK_Thai_leksun 0xdf0 +#define XK_Thai_leknung 0xdf1 +#define XK_Thai_leksong 0xdf2 +#define XK_Thai_leksam 0xdf3 +#define XK_Thai_leksi 0xdf4 +#define XK_Thai_lekha 0xdf5 +#define XK_Thai_lekhok 0xdf6 +#define XK_Thai_lekchet 0xdf7 +#define XK_Thai_lekpaet 0xdf8 +#define XK_Thai_lekkao 0xdf9 +#endif /* XK_THAI */ + +/* + * Korean + * Byte 3 = e + */ + +#ifdef XK_KOREAN + +#define XK_Hangul 0xff31 /* Hangul start/stop(toggle) */ +#define XK_Hangul_Start 0xff32 /* Hangul start */ +#define XK_Hangul_End 0xff33 /* Hangul end, English start */ +#define XK_Hangul_Hanja 0xff34 /* Start Hangul->Hanja Conversion */ +#define XK_Hangul_Jamo 0xff35 /* Hangul Jamo mode */ +#define XK_Hangul_Romaja 0xff36 /* Hangul Romaja mode */ +#define XK_Hangul_Codeinput 0xff37 /* Hangul code input mode */ +#define XK_Hangul_Jeonja 0xff38 /* Jeonja mode */ +#define XK_Hangul_Banja 0xff39 /* Banja mode */ +#define XK_Hangul_PreHanja 0xff3a /* Pre Hanja conversion */ +#define XK_Hangul_PostHanja 0xff3b /* Post Hanja conversion */ +#define XK_Hangul_SingleCandidate 0xff3c /* Single candidate */ +#define XK_Hangul_MultipleCandidate 0xff3d /* Multiple candidate */ +#define XK_Hangul_PreviousCandidate 0xff3e /* Previous candidate */ +#define XK_Hangul_Special 0xff3f /* Special symbols */ +#define XK_Hangul_switch 0xFF7E /* Alias for mode_switch */ + +/* Hangul Consonant Characters */ +#define XK_Hangul_Kiyeog 0xea1 +#define XK_Hangul_SsangKiyeog 0xea2 +#define XK_Hangul_KiyeogSios 0xea3 +#define XK_Hangul_Nieun 0xea4 +#define XK_Hangul_NieunJieuj 0xea5 +#define XK_Hangul_NieunHieuh 0xea6 +#define XK_Hangul_Dikeud 0xea7 +#define XK_Hangul_SsangDikeud 0xea8 +#define XK_Hangul_Rieul 0xea9 +#define XK_Hangul_RieulKiyeog 0xeaa +#define XK_Hangul_RieulMieum 0xeab +#define XK_Hangul_RieulPieub 0xeac +#define XK_Hangul_RieulSios 0xead +#define XK_Hangul_RieulTieut 0xeae +#define XK_Hangul_RieulPhieuf 0xeaf +#define XK_Hangul_RieulHieuh 0xeb0 +#define XK_Hangul_Mieum 0xeb1 +#define XK_Hangul_Pieub 0xeb2 +#define XK_Hangul_SsangPieub 0xeb3 +#define XK_Hangul_PieubSios 0xeb4 +#define XK_Hangul_Sios 0xeb5 +#define XK_Hangul_SsangSios 0xeb6 +#define XK_Hangul_Ieung 0xeb7 +#define XK_Hangul_Jieuj 0xeb8 +#define XK_Hangul_SsangJieuj 0xeb9 +#define XK_Hangul_Cieuc 0xeba +#define XK_Hangul_Khieuq 0xebb +#define XK_Hangul_Tieut 0xebc +#define XK_Hangul_Phieuf 0xebd +#define XK_Hangul_Hieuh 0xebe + +/* Hangul Vowel Characters */ +#define XK_Hangul_A 0xebf +#define XK_Hangul_AE 0xec0 +#define XK_Hangul_YA 0xec1 +#define XK_Hangul_YAE 0xec2 +#define XK_Hangul_EO 0xec3 +#define XK_Hangul_E 0xec4 +#define XK_Hangul_YEO 0xec5 +#define XK_Hangul_YE 0xec6 +#define XK_Hangul_O 0xec7 +#define XK_Hangul_WA 0xec8 +#define XK_Hangul_WAE 0xec9 +#define XK_Hangul_OE 0xeca +#define XK_Hangul_YO 0xecb +#define XK_Hangul_U 0xecc +#define XK_Hangul_WEO 0xecd +#define XK_Hangul_WE 0xece +#define XK_Hangul_WI 0xecf +#define XK_Hangul_YU 0xed0 +#define XK_Hangul_EU 0xed1 +#define XK_Hangul_YI 0xed2 +#define XK_Hangul_I 0xed3 + +/* Hangul syllable-final (JongSeong) Characters */ +#define XK_Hangul_J_Kiyeog 0xed4 +#define XK_Hangul_J_SsangKiyeog 0xed5 +#define XK_Hangul_J_KiyeogSios 0xed6 +#define XK_Hangul_J_Nieun 0xed7 +#define XK_Hangul_J_NieunJieuj 0xed8 +#define XK_Hangul_J_NieunHieuh 0xed9 +#define XK_Hangul_J_Dikeud 0xeda +#define XK_Hangul_J_Rieul 0xedb +#define XK_Hangul_J_RieulKiyeog 0xedc +#define XK_Hangul_J_RieulMieum 0xedd +#define XK_Hangul_J_RieulPieub 0xede +#define XK_Hangul_J_RieulSios 0xedf +#define XK_Hangul_J_RieulTieut 0xee0 +#define XK_Hangul_J_RieulPhieuf 0xee1 +#define XK_Hangul_J_RieulHieuh 0xee2 +#define XK_Hangul_J_Mieum 0xee3 +#define XK_Hangul_J_Pieub 0xee4 +#define XK_Hangul_J_PieubSios 0xee5 +#define XK_Hangul_J_Sios 0xee6 +#define XK_Hangul_J_SsangSios 0xee7 +#define XK_Hangul_J_Ieung 0xee8 +#define XK_Hangul_J_Jieuj 0xee9 +#define XK_Hangul_J_Cieuc 0xeea +#define XK_Hangul_J_Khieuq 0xeeb +#define XK_Hangul_J_Tieut 0xeec +#define XK_Hangul_J_Phieuf 0xeed +#define XK_Hangul_J_Hieuh 0xeee + +/* Ancient Hangul Consonant Characters */ +#define XK_Hangul_RieulYeorinHieuh 0xeef +#define XK_Hangul_SunkyeongeumMieum 0xef0 +#define XK_Hangul_SunkyeongeumPieub 0xef1 +#define XK_Hangul_PanSios 0xef2 +#define XK_Hangul_KkogjiDalrinIeung 0xef3 +#define XK_Hangul_SunkyeongeumPhieuf 0xef4 +#define XK_Hangul_YeorinHieuh 0xef5 + +/* Ancient Hangul Vowel Characters */ +#define XK_Hangul_AraeA 0xef6 +#define XK_Hangul_AraeAE 0xef7 + +/* Ancient Hangul syllable-final (JongSeong) Characters */ +#define XK_Hangul_J_PanSios 0xef8 +#define XK_Hangul_J_KkogjiDalrinIeung 0xef9 +#define XK_Hangul_J_YeorinHieuh 0xefa + +/* Korean currency symbol */ +#define XK_Korean_Won 0xeff + +#endif /* XK_KOREAN */ diff --git a/include/Xserver/colormap.h b/include/Xserver/colormap.h new file mode 100755 index 0000000..134f4a6 --- /dev/null +++ b/include/Xserver/colormap.h @@ -0,0 +1,239 @@ +/* + +Copyright (c) 1987 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. + + +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. + +*/ +/* $XConsortium: colormap.h,v 1.28 94/04/17 20:25:32 dpw Exp $ */ + + + + +/* $XFree86: xc/programs/Xserver/include/colormap.h,v 1.2 1997/01/14 22:22:38 dawes Exp $ */ +#ifndef CMAP_H +#define CMAP_H 1 + +#include "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( +#if NeedFunctionPrototypes + Colormap /*mid*/, + ScreenPtr /*pScreen*/, + VisualPtr /*pVisual*/, + ColormapPtr* /*ppcmap*/, + int /*alloc*/, + int /*client*/ +#endif +); + +extern int FreeColormap( +#if NeedFunctionPrototypes + pointer /*pmap*/, + XID /*mid*/ +#endif +); + +extern int TellLostMap( +#if NeedFunctionPrototypes + X11WindowPtr /*pwin*/, + pointer /* Colormap *pmid */ +#endif +); + +extern int TellGainedMap( +#if NeedFunctionPrototypes + X11WindowPtr /*pwin*/, + pointer /* Colormap *pmid */ +#endif +); + +extern int CopyColormapAndFree( +#if NeedFunctionPrototypes + Colormap /*mid*/, + ColormapPtr /*pSrc*/, + int /*client*/ +#endif +); + +extern int AllocColor( +#if NeedFunctionPrototypes + ColormapPtr /*pmap*/, + unsigned short* /*pred*/, + unsigned short* /*pgreen*/, + unsigned short* /*pblue*/, + Pixel* /*pPix*/, + int /*client*/ +#endif +); + +extern void FakeAllocColor( +#if NeedFunctionPrototypes + ColormapPtr /*pmap*/, + xColorItem * /*item*/ +#endif +); + +extern void FakeFreeColor( +#if NeedFunctionPrototypes + ColormapPtr /*pmap*/, + Pixel /*pixel*/ +#endif +); + +typedef int (*ColorCompareProcPtr)( +#if NeedNestedPrototypes + EntryPtr /*pent*/, + xrgb * /*prgb*/ +#endif +); + +extern int FindColor( +#if NeedFunctionPrototypes + ColormapPtr /*pmap*/, + EntryPtr /*pentFirst*/, + int /*size*/, + xrgb* /*prgb*/, + Pixel* /*pPixel*/, + int /*channel*/, + int /*client*/, + ColorCompareProcPtr /*comp*/ +#endif +); + +extern int QueryColors( +#if NeedFunctionPrototypes + ColormapPtr /*pmap*/, + int /*count*/, + Pixel* /*ppixIn*/, + xrgb* /*prgbList*/ +#endif +); + +extern int FreeClientPixels( +#if NeedFunctionPrototypes + pointer /*pcr*/, + XID /*fakeid*/ +#endif +); + +extern int AllocColorCells( +#if NeedFunctionPrototypes + int /*client*/, + ColormapPtr /*pmap*/, + int /*colors*/, + int /*planes*/, + Bool /*contig*/, + Pixel* /*ppix*/, + Pixel* /*masks*/ +#endif +); + +extern int AllocColorPlanes( +#if NeedFunctionPrototypes + int /*client*/, + ColormapPtr /*pmap*/, + int /*colors*/, + int /*r*/, + int /*g*/, + int /*b*/, + Bool /*contig*/, + Pixel* /*pixels*/, + Pixel* /*prmask*/, + Pixel* /*pgmask*/, + Pixel* /*pbmask*/ +#endif +); + +extern int FreeColors( +#if NeedFunctionPrototypes + ColormapPtr /*pmap*/, + int /*client*/, + int /*count*/, + Pixel* /*pixels*/, + Pixel /*mask*/ +#endif +); + +extern int StoreColors( +#if NeedFunctionPrototypes + ColormapPtr /*pmap*/, + int /*count*/, + xColorItem* /*defs*/ +#endif +); + +extern int IsMapInstalled( +#if NeedFunctionPrototypes + Colormap /*map*/, + X11WindowPtr /*pWin*/ +#endif +); + +#endif /* CMAP_H */ diff --git a/include/Xserver/cursor.h b/include/Xserver/cursor.h new file mode 100755 index 0000000..4069272 --- /dev/null +++ b/include/Xserver/cursor.h @@ -0,0 +1,152 @@ +/*********************************************************** + +Copyright (c) 1987 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. + + +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. + +******************************************************************/ +/* $XConsortium: cursor.h,v 1.22 94/04/17 20:25:34 dpw Exp $ */ +#ifndef CURSOR_H +#define CURSOR_H + +#include "misc.h" +#include "screenint.h" +#include "window.h" + +#define NullCursor ((CursorPtr)NULL) + +typedef struct _Cursor *CursorPtr; +typedef struct _CursorMetric *CursorMetricPtr; + +extern CursorPtr rootCursor; + +extern int FreeCursor( +#if NeedFunctionPrototypes + pointer /*pCurs*/, + XID /*cid*/ +#endif +); + +extern CursorPtr X11AllocCursor( +#if NeedFunctionPrototypes + unsigned char* /*psrcbits*/, + unsigned char* /*pmaskbits*/, + CursorMetricPtr /*cm*/, + unsigned /*foreRed*/, + unsigned /*foreGreen*/, + unsigned /*foreBlue*/, + unsigned /*backRed*/, + unsigned /*backGreen*/, + unsigned /*backBlue*/ +#endif +); + +extern int AllocGlyphCursor( +#if NeedFunctionPrototypes + 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*/ +#endif +); + +extern CursorPtr CreateRootCursor( +#if NeedFunctionPrototypes + char* /*pfilename*/, + unsigned int /*glyph*/ +#endif +); + +extern int ServerBitsFromGlyph( +#if NeedFunctionPrototypes + FontPtr /*pfont*/, + unsigned int /*ch*/, + register CursorMetricPtr /*cm*/, + unsigned char ** /*ppbits*/ +#endif +); + +extern Bool CursorMetricsFromGlyph( +#if NeedFunctionPrototypes + FontPtr /*pfont*/, + unsigned /*ch*/, + CursorMetricPtr /*cm*/ +#endif +); + +extern void CheckCursorConfinement( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/ +#endif +); + +extern void NewCurrentScreen( +#if NeedFunctionPrototypes + ScreenPtr /*newScreen*/, + int /*x*/, + int /*y*/ +#endif +); + +extern Bool PointerConfinedToScreen( +#if NeedFunctionPrototypes + void +#endif +); + +extern void GetSpritePosition( +#if NeedFunctionPrototypes + int * /*px*/, + int * /*py*/ +#endif +); + +#endif /* CURSOR_H */ diff --git a/include/Xserver/dix.h b/include/Xserver/dix.h new file mode 100755 index 0000000..2982b61 --- /dev/null +++ b/include/Xserver/dix.h @@ -0,0 +1,1103 @@ +/*********************************************************** + +Copyright (c) 1987 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. + + +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. + +******************************************************************/ +/* $XConsortium: dix.h /main/44 1996/12/15 21:24:57 rws $ */ +/* $XFree86: xc/programs/Xserver/include/dix.h,v 3.7 1996/12/31 04:17:46 dawes Exp $ */ + +#ifndef DIX_H +#define DIX_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_FIXED_SIZE(req, n)\ + if (((sizeof(req) >> 2) > client->req_len) || \ + (((sizeof(req) + (n) + 3) >> 2) != 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)\ + ((client->lastDrawableID == did) ? \ + client->lastDrawable : (DrawablePtr)LookupDrawable(did, client)) + +#ifdef XCSECURITY + +#define SECURITY_VERIFY_DRAWABLE(pDraw, did, client, mode)\ + if (client->lastDrawableID == did && !client->trustLevel)\ + pDraw = client->lastDrawable;\ + else \ + {\ + 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)\ + if (client->lastDrawableID == did && !client->trustLevel)\ + pDraw = client->lastDrawable;\ + else \ + {\ + pDraw = (DrawablePtr) SecurityLookupIDByClass(client, did, \ + RC_DRAWABLE, mode);\ + if (!pDraw) \ + {\ + client->errorValue = did; \ + return BadDrawable;\ + }\ + } + +#define SECURITY_VERIFY_GC(pGC, rid, client, mode)\ + if (client->lastGCID == rid && !client->trustLevel)\ + pGC = client->lastGC;\ + else\ + 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, SecurityUnknownAccess) + +#define VERIFY_GEOMETRABLE(pDraw, did, client)\ + SECURITY_VERIFY_GEOMETRABLE(pDraw, did, client, SecurityUnknownAccess) + +#define VERIFY_GC(pGC, rid, client)\ + SECURITY_VERIFY_GC(pGC, rid, client, SecurityUnknownAccess) + +#else /* not XCSECURITY */ + +#define VERIFY_DRAWABLE(pDraw, did, client)\ + if (client->lastDrawableID == did)\ + pDraw = client->lastDrawable;\ + else \ + {\ + 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)\ + if (client->lastDrawableID == did)\ + pDraw = client->lastDrawable;\ + else \ + {\ + pDraw = (DrawablePtr) LookupIDByClass(did, RC_DRAWABLE);\ + if (!pDraw) \ + {\ + client->errorValue = did; \ + return BadDrawable;\ + }\ + } + +#define VERIFY_GC(pGC, rid, client)\ + if (client->lastGCID == rid)\ + pGC = client->lastGC;\ + else\ + 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 != ((X11WindowPtr)_pDraw)->_whichBuffer)\ + {\ + ((X11WindowPtr)_pDraw)->_whichBuffer = thisbuf;\ + DbeValidateBuffer((X11WindowPtr)_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)\ + {\ + ((X11WindowPtr)_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)\ + if ((stuff->gc == INVALID) || (client->lastGCID != stuff->gc) ||\ + (client->lastDrawableID != drawID))\ + {\ + SECURITY_VERIFY_GEOMETRABLE(pDraw, drawID, client, SecurityWriteAccess);\ + SECURITY_VERIFY_GC(pGC, stuff->gc, client, SecurityReadAccess);\ + if ((pGC->depth != pDraw->depth) ||\ + (pGC->pScreen != pDraw->pScreen))\ + return (BadMatch);\ + client->lastDrawable = pDraw;\ + client->lastDrawableID = drawID;\ + client->lastGC = pGC;\ + client->lastGCID = stuff->gc;\ + }\ + else\ + {\ + pGC = client->lastGC;\ + pDraw = client->lastDrawable;\ + }\ + 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 (void) WriteToClient(pClient, (int)(size), (char *)(pReply)); + +#define WriteSwappedDataToClient(pClient, size, pbuf) \ + if ((pClient)->swapped) \ + (*(pClient)->pSwapReplyFunc)(pClient, (int)(size), pbuf); \ + else (void) WriteToClient (pClient, (int)(size), (char *)(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; + +#if !(defined(__alpha) || defined(__alpha__)) +typedef long HWEventQueueType; +#else +typedef int HWEventQueueType; +#endif +typedef HWEventQueueType* HWEventQueuePtr; + +extern HWEventQueuePtr checkForInput[2]; + +typedef struct _TimeStamp { + CARD32 months; /* really ~49.7 days */ + CARD32 milliseconds; +} TimeStamp; + +/* dispatch.c */ + +extern void SetInputCheck( +#if NeedFunctionPrototypes + HWEventQueuePtr /*c0*/, + HWEventQueuePtr /*c1*/ +#endif +); + +extern void CloseDownClient( +#if NeedFunctionPrototypes + ClientPtr /*client*/ +#endif +); + +extern void UpdateCurrentTime( +#if NeedFunctionPrototypes + void +#endif +); + +extern void UpdateCurrentTimeIf( +#if NeedFunctionPrototypes + void +#endif +); + +extern void InitSelections( +#if NeedFunctionPrototypes + void +#endif +); + +extern void FlushClientCaches( +#if NeedFunctionPrototypes + XID /*id*/ +#endif +); + +extern int dixDestroyPixmap( +#if NeedFunctionPrototypes + pointer /*value*/, + XID /*pid*/ +#endif +); + +extern void CloseDownRetainedResources( +#if NeedFunctionPrototypes + void +#endif +); + +extern void InitClient( +#if NeedFunctionPrototypes + ClientPtr /*client*/, + int /*i*/, + pointer /*ospriv*/ +#endif +); + +extern ClientPtr NextAvailableClient( +#if NeedFunctionPrototypes + pointer /*ospriv*/ +#endif +); + +extern void SendErrorToClient( +#if NeedFunctionPrototypes + ClientPtr /*client*/, + unsigned int /*majorCode*/, + unsigned int /*minorCode*/, + XID /*resId*/, + int /*errorCode*/ +#endif +); + +extern void DeleteWindowFromAnySelections( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/ +#endif +); + +extern void MarkClientException( +#if NeedFunctionPrototypes + ClientPtr /*client*/ +#endif +); + +extern int GetGeometry( +#if NeedFunctionPrototypes + ClientPtr /*client*/, + xGetGeometryReply* /* wa */ +#endif +); + +/* dixutils.c */ + +extern void CopyISOLatin1Lowered( +#if NeedFunctionPrototypes + unsigned char * /*dest*/, + unsigned char * /*source*/, + int /*length*/ +#endif +); + +#ifdef XCSECURITY + +extern X11WindowPtr SecurityLookupWindow( +#if NeedFunctionPrototypes + XID /*rid*/, + ClientPtr /*client*/, + Mask /*access_mode*/ +#endif +); + +extern pointer SecurityLookupDrawable( +#if NeedFunctionPrototypes + XID /*rid*/, + ClientPtr /*client*/, + Mask /*access_mode*/ +#endif +); + +extern X11WindowPtr LookupWindow( +#if NeedFunctionPrototypes + XID /*rid*/, + ClientPtr /*client*/ +#endif +); + +extern pointer LookupDrawable( +#if NeedFunctionPrototypes + XID /*rid*/, + ClientPtr /*client*/ +#endif +); + +#else + +extern X11WindowPtr LookupWindow( +#if NeedFunctionPrototypes + XID /*rid*/, + ClientPtr /*client*/ +#endif +); + +extern pointer LookupDrawable( +#if NeedFunctionPrototypes + XID /*rid*/, + ClientPtr /*client*/ +#endif +); + +#define SecurityLookupWindow(rid, client, access_mode) \ + LookupWindow(rid, client) + +#define SecurityLookupDrawable(rid, client, access_mode) \ + LookupDrawable(rid, client) + +#endif /* XCSECURITY */ + +extern ClientPtr LookupClient( +#if NeedFunctionPrototypes + XID /*rid*/, + ClientPtr /*client*/ +#endif +); + +extern void NoopDDA( +#if NeedVarargsPrototypes + void *, + ... +#endif +); + +extern int AlterSaveSetForClient( +#if NeedFunctionPrototypes + ClientPtr /*client*/, + X11WindowPtr /*pWin*/, + unsigned /*mode*/ +#endif +); + +extern void DeleteWindowFromAnySaveSet( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/ +#endif +); + +extern void BlockHandler( +#if NeedFunctionPrototypes + pointer /*pTimeout*/, + pointer /*pReadmask*/ +#endif +); + +extern void WakeupHandler( +#if NeedFunctionPrototypes + int /*result*/, + pointer /*pReadmask*/ +#endif +); + +typedef struct timeval ** OSTimePtr; + +typedef void (* BlockHandlerProcPtr)( +#if NeedNestedPrototypes + pointer /* blockData */, + OSTimePtr /* pTimeout */, + pointer /* pReadmask */ +#endif +); + +typedef void (* WakeupHandlerProcPtr)( +#if NeedNestedPrototypes + pointer /* blockData */, + int /* result */, + pointer /* pReadmask */ +#endif +); + +extern Bool RegisterBlockAndWakeupHandlers( +#if NeedFunctionPrototypes + BlockHandlerProcPtr /*blockHandler*/, + WakeupHandlerProcPtr /*wakeupHandler*/, + pointer /*blockData*/ +#endif +); + +extern void RemoveBlockAndWakeupHandlers( +#if NeedFunctionPrototypes + BlockHandlerProcPtr /*blockHandler*/, + WakeupHandlerProcPtr /*wakeupHandler*/, + pointer /*blockData*/ +#endif +); + +extern void InitBlockAndWakeupHandlers( +#if NeedFunctionPrototypes + void +#endif +); + +extern void ProcessWorkQueue( +#if NeedFunctionPrototypes + void +#endif +); + +extern Bool QueueWorkProc( +#if NeedFunctionPrototypes + Bool (* /*function*/)( +#if NeedNestedPrototypes + ClientPtr /*clientUnused*/, + pointer /*closure*/ +#endif + ), + ClientPtr /*client*/, + pointer /*closure*/ +#endif +); + +typedef Bool (* ClientSleepProcPtr)( +#if NeedFunctionPrototypes + ClientPtr /*client*/, + pointer /*closure*/ +#endif +); + +extern Bool ClientSleep( +#if NeedFunctionPrototypes + ClientPtr /*client*/, + ClientSleepProcPtr /* function */, + pointer /*closure*/ +#endif +); + +extern Bool ClientSignal( +#if NeedFunctionPrototypes + ClientPtr /*client*/ +#endif +); + +extern void ClientWakeup( +#if NeedFunctionPrototypes + ClientPtr /*client*/ +#endif +); + +extern Bool ClientIsAsleep( +#if NeedFunctionPrototypes + ClientPtr /*client*/ +#endif +); + +/* atom.c */ + +extern Atom MakeAtom( +#if NeedFunctionPrototypes + char * /*string*/, + unsigned /*len*/, + Bool /*makeit*/ +#endif +); + +extern Bool ValidAtom( +#if NeedFunctionPrototypes + Atom /*atom*/ +#endif +); + +extern char *NameForAtom( +#if NeedFunctionPrototypes + Atom /*atom*/ +#endif +); + +extern void AtomError( +#if NeedFunctionPrototypes + void +#endif +); + +extern void FreeAllAtoms( +#if NeedFunctionPrototypes + void +#endif +); + +extern void InitAtoms( +#if NeedFunctionPrototypes + void +#endif +); + +/* events.c */ + +extern void SetMaskForEvent( +#if NeedFunctionPrototypes + Mask /* mask */, + int /* event */ +#endif +); + +extern Bool PointerConfinedToScreen( +#if NeedFunctionPrototypes + void +#endif +); + +extern Bool IsParent( +#if NeedFunctionPrototypes + X11WindowPtr /* maybeparent */, + X11WindowPtr /* child */ +#endif +); + +extern X11WindowPtr GetCurrentRootWindow( +#if NeedFunctionPrototypes + void +#endif +); + +extern X11WindowPtr GetSpriteWindow( +#if NeedFunctionPrototypes + void +#endif +); + +extern void GetSpritePosition( +#if NeedFunctionPrototypes + int * /* px */, + int * /* py */ +#endif +); + +extern void NoticeEventTime( +#if NeedFunctionPrototypes + xEventPtr /* xE */ +#endif +); + +extern void EnqueueEvent( +#if NeedFunctionPrototypes + xEventPtr /* xE */, + DeviceIntPtr /* device */, + int /* count */ +#endif +); + +extern void ComputeFreezes( +#if NeedFunctionPrototypes + void +#endif +); + +extern void CheckGrabForSyncs( +#if NeedFunctionPrototypes + DeviceIntPtr /* dev */, + Bool /* thisMode */, + Bool /* otherMode */ +#endif +); + +extern void ActivatePointerGrab( +#if NeedFunctionPrototypes + DeviceIntPtr /* mouse */, + GrabPtr /* grab */, + TimeStamp /* time */, + Bool /* autoGrab */ +#endif +); + +extern void DeactivatePointerGrab( +#if NeedFunctionPrototypes + DeviceIntPtr /* mouse */ +#endif +); + +extern void ActivateKeyboardGrab( +#if NeedFunctionPrototypes + DeviceIntPtr /* keybd */, + GrabPtr /* grab */, + TimeStamp /* time */, + Bool /* passive */ +#endif +); + +extern void DeactivateKeyboardGrab( +#if NeedFunctionPrototypes + DeviceIntPtr /* keybd */ +#endif +); + +extern void AllowSome( +#if NeedFunctionPrototypes + ClientPtr /* client */, + TimeStamp /* time */, + DeviceIntPtr /* thisDev */, + int /* newState */ +#endif +); + +extern void ReleaseActiveGrabs( +#if NeedFunctionPrototypes +ClientPtr client +#endif +); + +extern int DeliverEventsToWindow( +#if NeedFunctionPrototypes + X11WindowPtr /* pWin */, + xEventPtr /* pEvents */, + int /* count */, + Mask /* filter */, + GrabPtr /* grab */, + int /* mskidx */ +#endif +); + +extern int DeliverDeviceEvents( +#if NeedFunctionPrototypes + X11WindowPtr /* pWin */, + xEventPtr /* xE */, + GrabPtr /* grab */, + X11WindowPtr /* stopAt */, + DeviceIntPtr /* dev */, + int /* count */ +#endif +); + +extern void DefineInitialRootWindow( +#if NeedFunctionPrototypes + X11WindowPtr /* win */ +#endif +); + +extern void WindowHasNewCursor( +#if NeedFunctionPrototypes + X11WindowPtr /* pWin */ +#endif +); + +extern Bool CheckDeviceGrabs( +#if NeedFunctionPrototypes + DeviceIntPtr /* device */, + xEventPtr /* xE */, + int /* checkFirst */, + int /* count */ +#endif +); + +extern void DeliverFocusedEvent( +#if NeedFunctionPrototypes + DeviceIntPtr /* keybd */, + xEventPtr /* xE */, + X11WindowPtr /* window */, + int /* count */ +#endif +); + +extern void DeliverGrabbedEvent( +#if NeedFunctionPrototypes + xEventPtr /* xE */, + DeviceIntPtr /* thisDev */, + Bool /* deactivateGrab */, + int /* count */ +#endif +); + +extern void RecalculateDeliverableEvents( +#if NeedFunctionPrototypes + X11WindowPtr /* pWin */ +#endif +); + +extern int OtherClientGone( +#if NeedFunctionPrototypes + pointer /* value */, + XID /* id */ +#endif +); + +extern void DoFocusEvents( +#if NeedFunctionPrototypes + DeviceIntPtr /* dev */, + X11WindowPtr /* fromWin */, + X11WindowPtr /* toWin */, + int /* mode */ +#endif +); + +extern int SetInputFocus( +#if NeedFunctionPrototypes + ClientPtr /* client */, + DeviceIntPtr /* dev */, + Window /* focusID */, + CARD8 /* revertTo */, + Time /* ctime */, + Bool /* followOK */ +#endif +); + +extern int GrabDevice( +#if NeedFunctionPrototypes + ClientPtr /* client */, + DeviceIntPtr /* dev */, + unsigned /* this_mode */, + unsigned /* other_mode */, + Window /* grabWindow */, + unsigned /* ownerEvents */, + Time /* ctime */, + Mask /* mask */, + CARD8 * /* status */ +#endif +); + +extern void InitEvents( +#if NeedFunctionPrototypes + void +#endif +); + +extern void DeleteWindowFromAnyEvents( +#if NeedFunctionPrototypes + X11WindowPtr /* pWin */, + Bool /* freeResources */ +#endif +); + +extern void CheckCursorConfinement( +#if NeedFunctionPrototypes + X11WindowPtr /* pWin */ +#endif +); + +extern Mask EventMaskForClient( +#if NeedFunctionPrototypes + X11WindowPtr /* pWin */, + ClientPtr /* client */ +#endif +); + + + +extern int DeliverEvents( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/, + xEventPtr /*xE*/, + int /*count*/, + X11WindowPtr /*otherParent*/ +#endif +); + +extern void WriteEventsToClient( +#if NeedFunctionPrototypes + ClientPtr /*pClient*/, + int /*count*/, + xEventPtr /*events*/ +#endif +); + +extern int TryClientEvents( +#if NeedFunctionPrototypes + ClientPtr /*client*/, + xEventPtr /*pEvents*/, + int /*count*/, + Mask /*mask*/, + Mask /*filter*/, + GrabPtr /*grab*/ +#endif +); + +extern int EventSelectForWindow( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/, + ClientPtr /*client*/, + Mask /*mask*/ +#endif +); + +extern int EventSuppressForWindow( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/, + ClientPtr /*client*/, + Mask /*mask*/, + Bool * /*checkOptional*/ +#endif +); + +extern int MaybeDeliverEventsToClient( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/, + xEventPtr /*pEvents*/, + int /*count*/, + Mask /*filter*/, + ClientPtr /*dontClient*/ +#endif +); + +extern void WindowsRestructured( +#if NeedFunctionPrototypes + void +#endif +); + +extern void ResetClientPrivates( +#if NeedFunctionPrototypes + void +#endif +); + +extern int AllocateClientPrivateIndex( +#if NeedFunctionPrototypes + void +#endif +); + +extern Bool AllocateClientPrivate( +#if NeedFunctionPrototypes + int /*index*/, + unsigned /*amount*/ +#endif +); + +/* + * callback manager stuff + */ + +#ifndef _XTYPEDEF_CALLBACKLISTPTR +typedef struct _CallbackList *CallbackListPtr; /* also in misc.h */ +#define _XTYPEDEF_CALLBACKLISTPTR +#endif + +typedef void (*CallbackProcPtr) ( +#if NeedNestedPrototypes + CallbackListPtr *, pointer, pointer +#endif +); + +typedef Bool (*AddCallbackProcPtr) ( +#if NeedNestedPrototypes + CallbackListPtr *, CallbackProcPtr, pointer +#endif +); + +typedef Bool (*DeleteCallbackProcPtr) ( +#if NeedNestedPrototypes + CallbackListPtr *, CallbackProcPtr, pointer +#endif +); + +typedef void (*CallCallbacksProcPtr) ( +#if NeedNestedPrototypes + CallbackListPtr *, pointer +#endif +); + +typedef void (*DeleteCallbackListProcPtr) ( +#if NeedNestedPrototypes + CallbackListPtr * +#endif +); + +typedef struct _CallbackProcs { + AddCallbackProcPtr AddCallback; + DeleteCallbackProcPtr DeleteCallback; + CallCallbacksProcPtr CallCallbacks; + DeleteCallbackListProcPtr DeleteCallbackList; +} CallbackFuncsRec, *CallbackFuncsPtr; + +extern Bool CreateCallbackList( +#if NeedFunctionPrototypes + CallbackListPtr * /*pcbl*/, + CallbackFuncsPtr /*cbfuncs*/ +#endif +); + +extern Bool AddCallback( +#if NeedFunctionPrototypes + CallbackListPtr * /*pcbl*/, + CallbackProcPtr /*callback*/, + pointer /*data*/ +#endif +); + +extern Bool DeleteCallback( +#if NeedFunctionPrototypes + CallbackListPtr * /*pcbl*/, + CallbackProcPtr /*callback*/, + pointer /*data*/ +#endif +); + +extern void CallCallbacks( +#if NeedFunctionPrototypes + CallbackListPtr * /*pcbl*/, + pointer /*call_data*/ +#endif +); + +extern void DeleteCallbackList( +#if NeedFunctionPrototypes + CallbackListPtr * /*pcbl*/ +#endif +); + +extern void InitCallbackManager( +#if NeedFunctionPrototypes + void +#endif +); + +/* + * 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; + +#endif /* DIX_H */ diff --git a/include/Xserver/gc.h b/include/Xserver/gc.h new file mode 100755 index 0000000..37e362d --- /dev/null +++ b/include/Xserver/gc.h @@ -0,0 +1,232 @@ +/*********************************************************** + +Copyright (c) 1987 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. + + +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. + +******************************************************************/ +/* $XConsortium: gc.h /main/16 1996/08/01 19:18:17 dpw $ */ + +#ifndef GC_H +#define GC_H + +#include "misc.h" /* for Bool */ +#include "X11/X.h" /* for GContext, Mask */ +#include "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( +#if NeedFunctionPrototypes + DrawablePtr /*pDraw*/, + GCPtr /*pGC*/ +#endif +); + +extern int ChangeGC( +#if NeedFunctionPrototypes + GCPtr/*pGC*/, + BITS32 /*mask*/, + XID* /*pval*/ +#endif +); + +extern int DoChangeGC( +#if NeedFunctionPrototypes + GCPtr/*pGC*/, + BITS32 /*mask*/, + XID* /*pval*/, + int /*fPointer*/ +#endif +); + +typedef union { + CARD32 val; + pointer ptr; +} ChangeGCVal, *ChangeGCValPtr; + +extern int dixChangeGC( +#if NeedFunctionPrototypes + ClientPtr /*client*/, + GCPtr /*pGC*/, + BITS32 /*mask*/, + CARD32 * /*pval*/, + ChangeGCValPtr /*pCGCV*/ +#endif +); + +extern GCPtr CreateGC( +#if NeedFunctionPrototypes + DrawablePtr /*pDrawable*/, + BITS32 /*mask*/, + XID* /*pval*/, + int* /*pStatus*/ +#endif +); + +extern int CopyGC( +#if NeedFunctionPrototypes + GCPtr/*pgcSrc*/, + GCPtr/*pgcDst*/, + BITS32 /*mask*/ +#endif +); + +extern int FreeGC( +#if NeedFunctionPrototypes + pointer /*pGC*/, + XID /*gid*/ +#endif +); + +extern void SetGCMask( +#if NeedFunctionPrototypes + GCPtr /*pGC*/, + Mask /*selectMask*/, + Mask /*newDataMask*/ +#endif +); + +extern GCPtr CreateScratchGC( +#if NeedFunctionPrototypes + ScreenPtr /*pScreen*/, + unsigned /*depth*/ +#endif +); + +extern void FreeGCperDepth( +#if NeedFunctionPrototypes + int /*screenNum*/ +#endif +); + +extern Bool CreateGCperDepth( +#if NeedFunctionPrototypes + int /*screenNum*/ +#endif +); + +extern Bool CreateDefaultStipple( +#if NeedFunctionPrototypes + int /*screenNum*/ +#endif +); + +extern void FreeDefaultStipple( +#if NeedFunctionPrototypes + int /*screenNum*/ +#endif +); + +extern int SetDashes( +#if NeedFunctionPrototypes + GCPtr /*pGC*/, + unsigned /*offset*/, + unsigned /*ndash*/, + unsigned char* /*pdash*/ +#endif +); + +extern int VerifyRectOrder( +#if NeedFunctionPrototypes + int /*nrects*/, + xRectangle* /*prects*/, + int /*ordering*/ +#endif +); + +extern int SetClipRects( +#if NeedFunctionPrototypes + GCPtr /*pGC*/, + int /*xOrigin*/, + int /*yOrigin*/, + int /*nrects*/, + xRectangle* /*prects*/, + int /*ordering*/ +#endif +); + +extern GCPtr GetScratchGC( +#if NeedFunctionPrototypes + unsigned /*depth*/, + ScreenPtr /*pScreen*/ +#endif +); + +extern void FreeScratchGC( +#if NeedFunctionPrototypes + GCPtr /*pGC*/ +#endif +); + +#endif /* GC_H */ diff --git a/include/Xserver/input.h b/include/Xserver/input.h new file mode 100755 index 0000000..63421de --- /dev/null +++ b/include/Xserver/input.h @@ -0,0 +1,535 @@ +/* $XConsortium: input.h /main/22 1996/09/25 00:50:39 dpw $ */ +/* $XFree86: xc/programs/Xserver/include/input.h,v 3.4 1996/12/23 07:09:28 dawes Exp $ */ +/************************************************************ + +Copyright (c) 1987 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. + + +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 "X11/Xmd.h" +#include "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)( +#if NeedNestedPrototypes + DeviceIntPtr /*device*/, + int /*what*/ +#endif +); + +typedef void (*ProcessInputProc)( +#if NeedNestedPrototypes + xEventPtr /*events*/, + DeviceIntPtr /*device*/, + int /*count*/ +#endif +); + +typedef struct _DeviceRec { + pointer 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 KeybdCtrl defaultKeyboardControl; +extern PtrCtrl defaultPointerControl; + +#undef AddInputDevice +extern DevicePtr AddInputDevice( +#if NeedFunctionPrototypes + DeviceProc /*deviceProc*/, + Bool /*autoStart*/ +#endif +); + +#define AddInputDevice(deviceProc, autoStart) \ + _AddInputDevice(deviceProc, autoStart) + +extern DeviceIntPtr _AddInputDevice( +#if NeedFunctionPrototypes + DeviceProc /*deviceProc*/, + Bool /*autoStart*/ +#endif +); + +extern Bool EnableDevice( +#if NeedFunctionPrototypes + DeviceIntPtr /*device*/ +#endif +); + +extern Bool DisableDevice( +#if NeedFunctionPrototypes + DeviceIntPtr /*device*/ +#endif +); + +extern int InitAndStartDevices( +#if NeedFunctionPrototypes + void +#endif +); + +extern void CloseDownDevices( +#if NeedFunctionPrototypes + void +#endif +); + +extern void RemoveDevice( +#if NeedFunctionPrototypes + DeviceIntPtr /*dev*/ +#endif +); + +extern int NumMotionEvents( +#if NeedFunctionPrototypes + void +#endif +); + +#undef RegisterPointerDevice +extern void RegisterPointerDevice( +#if NeedFunctionPrototypes + DevicePtr /*device*/ +#endif +); + +#define RegisterPointerDevice(device) \ + _RegisterPointerDevice(device) + +extern void _RegisterPointerDevice( +#if NeedFunctionPrototypes + DeviceIntPtr /*device*/ +#endif +); + +#undef RegisterKeyboardDevice +extern void RegisterKeyboardDevice( +#if NeedFunctionPrototypes + DevicePtr /*device*/ +#endif +); + +#define RegisterKeyboardDevice(device) \ + _RegisterKeyboardDevice(device) + +extern void _RegisterKeyboardDevice( +#if NeedFunctionPrototypes + DeviceIntPtr /*device*/ +#endif +); + +extern DevicePtr LookupKeyboardDevice( +#if NeedFunctionPrototypes + void +#endif +); + +extern DevicePtr LookupPointerDevice( +#if NeedFunctionPrototypes + void +#endif +); + +extern DevicePtr LookupDevice( +#if NeedFunctionPrototypes + int /* id */ +#endif +); + +extern void QueryMinMaxKeyCodes( +#if NeedFunctionPrototypes + KeyCode* /*minCode*/, + KeyCode* /*maxCode*/ +#endif +); + +extern Bool SetKeySymsMap( +#if NeedFunctionPrototypes + KeySymsPtr /*dst*/, + KeySymsPtr /*src*/ +#endif +); + +extern Bool InitKeyClassDeviceStruct( +#if NeedFunctionPrototypes + DeviceIntPtr /*device*/, + KeySymsPtr /*pKeySyms*/, + CARD8 /*pModifiers*/[] +#endif +); + +extern Bool InitButtonClassDeviceStruct( +#if NeedFunctionPrototypes + DeviceIntPtr /*device*/, + int /*numButtons*/, + CARD8* /*map*/ +#endif +); + +typedef int (*ValuatorMotionProcPtr)( +#if NeedNestedPrototypes + DeviceIntPtr /*pdevice*/, + xTimecoord * /*coords*/, + unsigned long /*start*/, + unsigned long /*stop*/, + ScreenPtr /*pScreen*/ +#endif +); + +extern Bool InitValuatorClassDeviceStruct( +#if NeedFunctionPrototypes + DeviceIntPtr /*device*/, + int /*numAxes*/, + ValuatorMotionProcPtr /* motionProc */, + int /*numMotionEvents*/, + int /*mode*/ +#endif +); + +extern Bool InitFocusClassDeviceStruct( +#if NeedFunctionPrototypes + DeviceIntPtr /*device*/ +#endif +); + +typedef void (*BellProcPtr)( +#if NeedNestedPrototypes + int /*percent*/, + DeviceIntPtr /*device*/, + pointer /*ctrl*/, + int +#endif +); + +typedef void (*KbdCtrlProcPtr)( +#if NeedNestedPrototypes + DeviceIntPtr /*device*/, + KeybdCtrl * /*ctrl*/ +#endif +); + +extern Bool InitKbdFeedbackClassDeviceStruct( +#if NeedFunctionPrototypes + DeviceIntPtr /*device*/, + BellProcPtr /*bellProc*/, + KbdCtrlProcPtr /*controlProc*/ +#endif +); + +typedef void (*PtrCtrlProcPtr)( +#if NeedNestedPrototypes + DeviceIntPtr /*device*/, + PtrCtrl * /*ctrl*/ +#endif +); + +extern Bool InitPtrFeedbackClassDeviceStruct( +#if NeedFunctionPrototypes + DeviceIntPtr /*device*/, + PtrCtrlProcPtr /*controlProc*/ +#endif +); + +typedef void (*StringCtrlProcPtr)( +#if NeedNestedPrototypes + DeviceIntPtr /*device*/, + StringCtrl * /*ctrl*/ +#endif +); + +extern Bool InitStringFeedbackClassDeviceStruct( +#if NeedFunctionPrototypes + DeviceIntPtr /*device*/, + StringCtrlProcPtr /*controlProc*/, + int /*max_symbols*/, + int /*num_symbols_supported*/, + KeySym* /*symbols*/ +#endif +); + +typedef void (*BellCtrlProcPtr)( +#if NeedNestedPrototypes + DeviceIntPtr /*device*/, + BellCtrl * /*ctrl*/ +#endif +); + +extern Bool InitBellFeedbackClassDeviceStruct( +#if NeedFunctionPrototypes + DeviceIntPtr /*device*/, + BellProcPtr /*bellProc*/, + BellCtrlProcPtr /*controlProc*/ +#endif +); + +typedef void (*LedCtrlProcPtr)( +#if NeedNestedPrototypes + DeviceIntPtr /*device*/, + LedCtrl * /*ctrl*/ +#endif +); + +extern Bool InitLedFeedbackClassDeviceStruct( +#if NeedFunctionPrototypes + DeviceIntPtr /*device*/, + LedCtrlProcPtr /*controlProc*/ +#endif +); + +typedef void (*IntegerCtrlProcPtr)( +#if NeedNestedPrototypes + DeviceIntPtr /*device*/, + IntegerCtrl * /*ctrl*/ +#endif +); + + +extern Bool InitIntegerFeedbackClassDeviceStruct( +#if NeedFunctionPrototypes + DeviceIntPtr /*device*/, + IntegerCtrlProcPtr /*controlProc*/ +#endif +); + +extern Bool InitPointerDeviceStruct( +#if NeedFunctionPrototypes + DevicePtr /*device*/, + CARD8* /*map*/, + int /*numButtons*/, + ValuatorMotionProcPtr /*motionProc*/, + PtrCtrlProcPtr /*controlProc*/, + int /*numMotionEvents*/ +#endif +); + +extern Bool InitKeyboardDeviceStruct( +#if NeedFunctionPrototypes + DevicePtr /*device*/, + KeySymsPtr /*pKeySyms*/, + CARD8 /*pModifiers*/[], + BellProcPtr /*bellProc*/, + KbdCtrlProcPtr /*controlProc*/ +#endif +); + +extern void SendMappingNotify( +#if NeedFunctionPrototypes + unsigned int /*request*/, + unsigned int /*firstKeyCode*/, + unsigned int /*count*/, + ClientPtr /* client */ +#endif +); + +extern Bool BadDeviceMap( +#if NeedFunctionPrototypes + BYTE* /*buff*/, + int /*length*/, + unsigned /*low*/, + unsigned /*high*/, + XID* /*errval*/ +#endif +); + +extern Bool AllModifierKeysAreUp( +#if NeedFunctionPrototypes + DeviceIntPtr /*device*/, + CARD8* /*map1*/, + int /*per1*/, + CARD8* /*map2*/, + int /*per2*/ +#endif +); + +extern void NoteLedState( +#if NeedFunctionPrototypes + DeviceIntPtr /*keybd*/, + int /*led*/, + Bool /*on*/ +#endif +); + +extern void MaybeStopHint( +#if NeedFunctionPrototypes + DeviceIntPtr /*device*/, + ClientPtr /*client*/ +#endif +); + +extern void ProcessPointerEvent( +#if NeedFunctionPrototypes + xEventPtr /*xE*/, + DeviceIntPtr /*mouse*/, + int /*count*/ +#endif +); + +extern void ProcessKeyboardEvent( +#if NeedFunctionPrototypes + xEventPtr /*xE*/, + DeviceIntPtr /*keybd*/, + int /*count*/ +#endif +); + +#ifdef XKB +extern void CoreProcessPointerEvent( +#if NeedFunctionPrototypes + xEventPtr /*xE*/, + DeviceIntPtr /*mouse*/, + int /*count*/ +#endif +); + +extern void CoreProcessKeyboardEvent( +#if NeedFunctionPrototypes + xEventPtr /*xE*/, + DeviceIntPtr /*keybd*/, + int /*count*/ +#endif +); +#endif + +extern Bool LegalModifier( +#if NeedFunctionPrototypes + unsigned int /*key*/, + DevicePtr /*pDev*/ +#endif +); + +extern void ProcessInputEvents( +#if NeedFunctionPrototypes + void +#endif +); + +extern void InitInput( +#if NeedFunctionPrototypes + int /*argc*/, + char ** /*argv*/ +#endif +); + +#endif /* INPUT_H */ diff --git a/include/Xserver/misc.h b/include/Xserver/misc.h new file mode 100755 index 0000000..f01f3e9 --- /dev/null +++ b/include/Xserver/misc.h @@ -0,0 +1,280 @@ +/*********************************************************** + +Copyright (c) 1987 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. + + +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. + +******************************************************************/ +/* $XConsortium: misc.h /main/28 1996/12/02 10:22:01 lehors $ */ +/* $XFree86: xc/programs/Xserver/include/misc.h,v 3.5 1996/12/23 07:09:29 dawes Exp $ */ +#ifndef MISC_H +#define MISC_H 1 +/* + * X internal definitions + * + */ + +extern unsigned long globalSerialNumber; +extern unsigned long serverGeneration; + +#include +#include +#include +#include + +#ifndef NULL +#ifndef X_NOT_STDC_ENV +#include +#else +#define NULL 0 +#endif +#endif + +#ifndef MAXSCREENS +#define MAXSCREENS 3 +#endif +#define MAXCLIENTS 128 +#define MAXDITS 1 +#define MAXEXTENSIONS 128 +#define MAXFORMATS 8 +#define MAXVISUALS_PER_SCREEN 50 + +#if NeedFunctionPrototypes +typedef void *pointer; +#else +typedef unsigned char *pointer; +#endif +typedef int Bool; +typedef unsigned long PIXEL; +typedef unsigned long ATOM; + + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +#ifndef _XTYPEDEF_FONTPTR +typedef struct _Font *FontPtr; /* also in fonts/include/font.h */ +#define _XTYPEDEF_FONTPTR +#endif + +#ifndef _XTYPEDEF_CLIENTPTR +typedef struct _Client *ClientPtr; /* also in dix.h */ +#define _XTYPEDEF_CLIENTPTR +#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 /* 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)) + +#define min(a, b) (((a) < (b)) ? (a) : (b)) +#define max(a, b) (((a) > (b)) ? (a) : (b)) +#if !defined(AMOEBA) && !defined(__EMX__) +#ifndef abs +#define abs(a) ((a) > 0 ? (a) : -(a)) +#endif +#else /* AMOEBA || __EMX__ */ +/* abs() is a function, not a macro; include the file declaring + * it in case we haven't done that yet. + */ +#include +#endif /* AMOEBA */ +#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)) + +#ifndef MAXSHORT +#define MAXSHORT 32767 +#endif +#ifndef MINSHORT +#define MINSHORT -MAXSHORT +#endif + + +/* 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)) + +/* byte swap a 32-bit value */ +#define swapl(x, n) { \ + 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; } + +/* byte swap a short */ +#define swaps(x, n) { \ + n = ((char *) (x))[0];\ + ((char *) (x))[0] = ((char *) (x))[1];\ + ((char *) (x))[1] = n; } + +/* copy 32-bit value from src to dst byteswapping on the way */ +#define cpswapl(src, dst) { \ + ((char *)&(dst))[0] = ((char *) &(src))[3];\ + ((char *)&(dst))[1] = ((char *) &(src))[2];\ + ((char *)&(dst))[2] = ((char *) &(src))[1];\ + ((char *)&(dst))[3] = ((char *) &(src))[0]; } + +/* copy short from src to dst byteswapping on the way */ +#define cpswaps(src, dst) { \ + ((char *) &(dst))[0] = ((char *) &(src))[1];\ + ((char *) &(dst))[1] = ((char *) &(src))[0]; } + +extern void SwapLongs( +#if NeedFunctionPrototypes + CARD32 *list, + unsigned long count +#endif +); + +extern void SwapShorts( +#if NeedFunctionPrototypes + short *list, + unsigned long count +#endif +); + +extern void MakePredeclaredAtoms( +#if NeedFunctionPrototypes + void +#endif +); + +extern int Ones( +#if NeedFunctionPrototypes + unsigned long /*mask*/ +#endif +); + +typedef struct _xPoint *DDXPointPtr; +typedef struct _Box *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/include/Xserver/miscstruct.h b/include/Xserver/miscstruct.h new file mode 100755 index 0000000..d99595f --- /dev/null +++ b/include/Xserver/miscstruct.h @@ -0,0 +1,73 @@ +/* $XConsortium: miscstruct.h,v 5.5 94/04/17 20:25:50 dpw Exp $ */ +/* $XFree86: xc/programs/Xserver/include/miscstruct.h,v 3.0 1996/02/18 03:45:10 dawes Exp $ */ +/*********************************************************** + +Copyright (c) 1987 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. + + +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 "misc.h" +#include "X11/Xprotostr.h" + +typedef xPoint DDXPointRec; + +typedef struct _Box { + short x1, y1, x2, y2; +} BoxRec; + +typedef union _DevUnion { + pointer ptr; + long val; + unsigned long uval; + pointer (*fptr)( +#if NeedFunctionPrototypes + void +#endif + ); +} DevUnion; + +#endif /* MISCSTRUCT_H */ diff --git a/include/Xserver/opaque.h b/include/Xserver/opaque.h new file mode 100755 index 0000000..7de1ad3 --- /dev/null +++ b/include/Xserver/opaque.h @@ -0,0 +1,74 @@ +/* $XConsortium: opaque.h,v 1.19 94/04/17 20:25:51 dpw Exp $ */ +/* + +Copyright (c) 1987 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. + +*/ +/* $XFree86: xc/programs/Xserver/include/opaque.h,v 1.2.2.1 1997/06/01 12:33:43 dawes Exp $ */ + +#ifndef OPAQUE_H +#define OPAQUE_H + +#include + +extern char *defaultFontPath; +extern char *defaultTextFont; +extern char *defaultCursorFont; +extern char *rgbPath; +extern int MaxClients; +extern char isItTimeToYield; +extern 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 CARD32 ScreenSaverTime; +extern CARD32 ScreenSaverInterval; +extern int ScreenSaverBlanking; +extern int ScreenSaverAllowExposures; +extern int argcGlobal; +extern char **argvGlobal; + +#if 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 + +#endif /* OPAQUE_H */ diff --git a/include/Xserver/os.h b/include/Xserver/os.h new file mode 100755 index 0000000..abeac7e --- /dev/null +++ b/include/Xserver/os.h @@ -0,0 +1,776 @@ +/*********************************************************** + +Copyright (c) 1987 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. + + +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. + +******************************************************************/ + +/* $XConsortium: os.h /main/60 1996/12/15 21:25:13 rws $ */ +/* $XFree86: xc/programs/Xserver/include/os.h,v 3.16.2.1 1998/01/22 10:47:13 dawes Exp $ */ + +#ifndef OS_H +#define OS_H +#include "misc.h" +#define ALLOCATE_LOCAL_FALLBACK(_size) Xalloc((unsigned long)(_size)) +#define DEALLOCATE_LOCAL_FALLBACK(_ptr) Xfree((pointer)(_ptr)) +#include "Xalloca.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 1048575 +#endif + +typedef pointer FID; +typedef struct _FontPathRec *FontPathPtr; +typedef struct _NewClientRec *NewClientPtr; + +#define xnfalloc(size) XNFalloc((unsigned long)(size)) +#define xnfrealloc(ptr, size) XNFrealloc((pointer)(ptr), (unsigned long)(size)) + +#define xalloc(size) Xalloc((unsigned long)(size)) +#define xnfalloc(size) XNFalloc((unsigned long)(size)) +#define xcalloc(_num, _size) Xcalloc((unsigned long)(_num)*(unsigned long)(_size)) +#define xrealloc(ptr, size) Xrealloc((pointer)(ptr), (unsigned long)(size)) +#define xnfrealloc(ptr, size) XNFrealloc((pointer)(ptr), (unsigned long)(size)) +#define xfree(ptr) Xfree((pointer)(ptr)) + +#ifdef SCO +#include +#endif +#ifndef X_NOT_STDC_ENV +#include +#else +#ifdef SYSV +#include +#else +#include +#endif +#endif + +/* have to put $(SIGNAL_DEFINES) in DEFINES in Imakefile to get this right */ +#ifdef SIGNALRETURNSINT +#define SIGVAL int +#else +#define SIGVAL void +#endif + +extern Bool OsDelayInitColors; + +extern int WaitForSomething( +#if NeedFunctionPrototypes + int* /*pClientsReady*/ +#endif +); + +#ifdef LBX +#define ReadRequestFromClient(client) ((client)->readRequest(client)) +extern int StandardReadRequestFromClient( +#if NeedFunctionPrototypes + ClientPtr /*client*/ +#endif +); +#else +extern int ReadRequestFromClient( +#if NeedFunctionPrototypes + ClientPtr /*client*/ +#endif +); +#endif /* LBX */ + +extern Bool InsertFakeRequest( +#if NeedFunctionPrototypes + ClientPtr /*client*/, + char* /*data*/, + int /*count*/ +#endif +); + +extern int ResetCurrentRequest( +#if NeedFunctionPrototypes + ClientPtr /*client*/ +#endif +); + +extern void FlushAllOutput( +#if NeedFunctionPrototypes + void +#endif +); + +extern void FlushIfCriticalOutputPending( +#if NeedFunctionPrototypes + void +#endif +); + +extern void SetCriticalOutputPending( +#if NeedFunctionPrototypes + void +#endif +); + +extern int WriteToClient( +#if NeedFunctionPrototypes + ClientPtr /*who*/, + int /*count*/, + char* /*buf*/ +#endif +); + +extern void ResetOsBuffers( +#if NeedFunctionPrototypes + void +#endif +); + +extern void CreateWellKnownSockets( +#if NeedFunctionPrototypes + void +#endif +); + +extern void ResetWellKnownSockets( +#if NeedFunctionPrototypes + void +#endif +); + +extern XID +AuthorizationIDOfClient( +#if NeedFunctionPrototypes + ClientPtr /*client*/ +#endif +); + +extern char *ClientAuthorized( +#if NeedFunctionPrototypes + ClientPtr /*client*/, + unsigned int /*proto_n*/, + char* /*auth_proto*/, + unsigned int /*string_n*/, + char* /*auth_string*/ +#endif +); + +extern Bool EstablishNewConnections( +#if NeedFunctionPrototypes + ClientPtr /*clientUnused*/, + pointer /*closure*/ +#endif +); + +extern void CheckConnections( +#if NeedFunctionPrototypes + void +#endif +); + +extern void CloseDownConnection( +#if NeedFunctionPrototypes + ClientPtr /*client*/ +#endif +); + +extern int AddEnabledDevice( +#if NeedFunctionPrototypes + int /*fd*/ +#endif +); + +extern int RemoveEnabledDevice( +#if NeedFunctionPrototypes + int /*fd*/ +#endif +); + +extern int OnlyListenToOneClient( +#if NeedFunctionPrototypes + ClientPtr /*client*/ +#endif +); + +extern int ListenToAllClients( +#if NeedFunctionPrototypes + void +#endif +); + +extern int IgnoreClient( +#if NeedFunctionPrototypes + ClientPtr /*client*/ +#endif +); + +extern int AttendClient( +#if NeedFunctionPrototypes + ClientPtr /*client*/ +#endif +); + +extern int MakeClientGrabImpervious( +#if NeedFunctionPrototypes + ClientPtr /*client*/ +#endif +); + +extern int MakeClientGrabPervious( +#if NeedFunctionPrototypes + ClientPtr /*client*/ +#endif +); + +extern void Error( +#if NeedFunctionPrototypes + char* /*str*/ +#endif +); + +extern CARD32 GetTimeInMillis( +#if NeedFunctionPrototypes + void +#endif +); + +extern int AdjustWaitForDelay( +#if NeedFunctionPrototypes + pointer /*waitTime*/, + unsigned long /*newdelay*/ +#endif +); + +typedef struct _OsTimerRec *OsTimerPtr; + +typedef CARD32 (*OsTimerCallback)( +#if NeedFunctionPrototypes + OsTimerPtr /* timer */, + CARD32 /* time */, + pointer /* arg */ +#endif +); + +extern void TimerInit( +#if NeedFunctionPrototypes + void +#endif +); + +extern Bool TimerForce( +#if NeedFunctionPrototypes + OsTimerPtr /* timer */ +#endif +); + +#define TimerAbsolute (1<<0) +#define TimerForceOld (1<<1) + +extern OsTimerPtr TimerSet( +#if NeedFunctionPrototypes + OsTimerPtr /* timer */, + int /* flags */, + CARD32 /* millis */, + OsTimerCallback /* func */, + pointer /* arg */ +#endif +); + +extern void TimerCheck( +#if NeedFunctionPrototypes + void +#endif +); + +extern void TimerCancel( +#if NeedFunctionPrototypes + OsTimerPtr /* pTimer */ +#endif +); + +extern void TimerFree( +#if NeedFunctionPrototypes + OsTimerPtr /* pTimer */ +#endif +); + +extern SIGVAL AutoResetServer( +#if NeedFunctionPrototypes + int /*sig*/ +#endif +); + +extern SIGVAL GiveUp( +#if NeedFunctionPrototypes + int /*sig*/ +#endif +); + +extern void UseMsg( +#if NeedFunctionPrototypes + void +#endif +); + +extern void ProcessCommandLine( +#if NeedFunctionPrototypes + int /*argc*/, + char* /*argv*/[] +#endif +); + +extern unsigned long *Xalloc( +#if NeedFunctionPrototypes + unsigned long /*amount*/ +#endif +); + +extern unsigned long *XNFalloc( +#if NeedFunctionPrototypes + unsigned long /*amount*/ +#endif +); + +extern unsigned long *Xcalloc( +#if NeedFunctionPrototypes + unsigned long /*amount*/ +#endif +); + +extern unsigned long *Xrealloc( +#if NeedFunctionPrototypes + pointer /*ptr*/, + unsigned long /*amount*/ +#endif +); + +extern unsigned long *XNFrealloc( +#if NeedFunctionPrototypes + pointer /*ptr*/, + unsigned long /*amount*/ +#endif +); + +extern void Xfree( +#if NeedFunctionPrototypes + pointer /*ptr*/ +#endif +); + +extern void OsInitAllocator( +#if NeedFunctionPrototypes + void +#endif +); + +typedef SIGVAL (*OsSigHandlerPtr)( +#if NeedFunctionPrototypes + int /* sig */ +#endif +); + +extern OsSigHandlerPtr OsSignal( +#if NeedFunctionPrototypes + int /* sig */, + OsSigHandlerPtr /* handler */ +#endif +); + +extern int auditTrailLevel; + +extern void AuditF( +#if NeedVarargsPrototypes + char* /*f*/, + ... +#endif +); + +extern void FatalError( +#if NeedVarargsPrototypes + char* /*f*/, + ... +#endif +) +#if __GNUC__ == 2 && __GNUC_MINOR__ > 4 +__attribute((noreturn)) +#endif +; + +extern void ErrorF( +#if NeedVarargsPrototypes + char* /*f*/, + ... +#endif +); + +#ifdef SERVER_LOCK +extern void LockServer( +#if NeedFunctionPrototypes + void +#endif +); + +extern void UnlockServer( +#if NeedFunctionPrototypes + void +#endif +); +#endif + +extern int OsLookupColor( +#if NeedFunctionPrototypes + int /*screen*/, + char * /*name*/, + unsigned /*len*/, + unsigned short * /*pred*/, + unsigned short * /*pgreen*/, + unsigned short * /*pblue*/ +#endif +); + +extern void OsInit( +#if NeedFunctionPrototypes + void +#endif +); + +extern void OsCleanup( +#if NeedFunctionPrototypes + void +#endif +); + +extern void OsVendorFatalError( +#if NeedFunctionPrototypes + void +#endif +); + +extern void OsVendorInit( +#if NeedFunctionPrototypes + void +#endif +); + +extern int OsInitColors( +#if NeedFunctionPrototypes + void +#endif +); + +#if !defined(WIN32) && !defined(__EMX__) +extern int System( +#if NeedFunctionPrototypes + char * +#endif +); + +extern pointer Popen( +#if NeedFunctionPrototypes + char *, + char * +#endif +); + +extern int Pclose( +#if NeedFunctionPrototypes + pointer +#endif +); +#else +#define System(a) system(a) +#define Popen(a,b) popen(a,b) +#define Pclose(a) pclose(a) +#endif + +extern int AddHost( +#if NeedFunctionPrototypes + ClientPtr /*client*/, + int /*family*/, + unsigned /*length*/, + pointer /*pAddr*/ +#endif +); + +extern Bool ForEachHostInFamily ( +#if NeedFunctionPrototypes + int /*family*/, + Bool (* /*func*/ )( +#if NeedNestedPrototypes + unsigned char * /* addr */, + short /* len */, + pointer /* closure */ +#endif + ), + pointer /*closure*/ +#endif +); + +extern int RemoveHost( +#if NeedFunctionPrototypes + ClientPtr /*client*/, + int /*family*/, + unsigned /*length*/, + pointer /*pAddr*/ +#endif +); + +extern int GetHosts( +#if NeedFunctionPrototypes + pointer * /*data*/, + int * /*pnHosts*/, + int * /*pLen*/, + BOOL * /*pEnabled*/ +#endif +); + +typedef struct sockaddr * sockaddrPtr; + +extern int InvalidHost( +#if NeedFunctionPrototypes + sockaddrPtr /*saddr*/, + int /*len*/ +#endif +); + +extern int LocalClient( +#if NeedFunctionPrototypes + ClientPtr /* client */ +#endif +); + +extern int ChangeAccessControl( +#if NeedFunctionPrototypes + ClientPtr /*client*/, + int /*fEnabled*/ +#endif +); + +extern int GetAccessControl( +#if NeedFunctionPrototypes + void +#endif +); + + +extern void AddLocalHosts( +#if NeedFunctionPrototypes + void +#endif +); + +extern void ResetHosts( +#if NeedFunctionPrototypes + char *display +#endif +); + +extern void EnableLocalHost( +#if NeedFunctionPrototypes + void +#endif +); + +extern void DisableLocalHost( +#if NeedFunctionPrototypes + void +#endif +); + +extern void AccessUsingXdmcp( +#if NeedFunctionPrototypes + void +#endif +); + +extern void DefineSelf( +#if NeedFunctionPrototypes + int /*fd*/ +#endif +); + +extern void AugmentSelf( +#if NeedFunctionPrototypes + pointer /*from*/, + int /*len*/ +#endif +); + +extern void InitAuthorization( +#if NeedFunctionPrototypes + char * /*filename*/ +#endif +); + +extern int LoadAuthorization( +#if NeedFunctionPrototypes + void +#endif +); + +extern void RegisterAuthorizations( +#if NeedFunctionPrototypes + void +#endif +); + +extern XID CheckAuthorization( +#if NeedFunctionPrototypes + unsigned int /*namelength*/, + char * /*name*/, + unsigned int /*datalength*/, + char * /*data*/, + ClientPtr /*client*/, + char ** /*reason*/ +#endif +); + +extern void ResetAuthorization( +#if NeedFunctionPrototypes + void +#endif +); + +extern int AddAuthorization( +#if NeedFunctionPrototypes + unsigned int /*name_length*/, + char * /*name*/, + unsigned int /*data_length*/, + char * /*data*/ +#endif +); + +extern XID GenerateAuthorization( +#if NeedFunctionPrototypes + unsigned int /* name_length */, + char * /* name */, + unsigned int /* data_length */, + char * /* data */, + unsigned int * /* data_length_return */, + char ** /* data_return */ +#endif +); + +extern void ExpandCommandLine( +#if NeedFunctionPrototypes + int * /*pargc*/, + char *** /*pargv*/ +#endif +); + +extern int ddxProcessArgument( +#if NeedFunctionPrototypes + int /*argc*/, + char * /*argv*/ [], + int /*i*/ +#endif +); + +/* + * idiom processing stuff + */ + +xReqPtr PeekNextRequest( +#if NeedFunctionPrototypes + xReqPtr req, ClientPtr client, Bool readmore +#endif +); + +void SkipRequests( +#if NeedFunctionPrototypes + xReqPtr req, ClientPtr client, int numskipped +#endif +); + +/* 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_ 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; + pointer replyData; + unsigned long dataLenBytes; + unsigned long bytesRemaining; + Bool startOfReply; +} ReplyInfoRec; + +/* stuff for FlushCallback */ +extern CallbackListPtr FlushCallback; + +#endif /* OS_H */ diff --git a/include/Xserver/pixmap.h b/include/Xserver/pixmap.h new file mode 100755 index 0000000..5fdc2d0 --- /dev/null +++ b/include/Xserver/pixmap.h @@ -0,0 +1,124 @@ +/* $XConsortium: pixmap.h,v 5.6 94/04/17 20:25:53 dpw Exp $ */ +/*********************************************************** + +Copyright (c) 1987 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. + + +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( +#if NeedFunctionPrototypes + ScreenPtr /*pScreen*/, + int /*width*/, + int /*height*/, + int /*depth*/, + int /*bitsPerPixel*/, + int /*devKind*/, + pointer /*pPixData*/ +#endif +); + +extern void FreeScratchPixmapHeader( +#if NeedFunctionPrototypes + PixmapPtr /*pPixmap*/ +#endif +); + +extern Bool CreateScratchPixmapsForScreen( +#if NeedFunctionPrototypes + int /*scrnum*/ +#endif +); + +extern void FreeScratchPixmapsForScreen( +#if NeedFunctionPrototypes + int /*scrnum*/ +#endif +); + +extern PixmapPtr AllocatePixmap( +#if NeedFunctionPrototypes + ScreenPtr /*pScreen*/, + int /*pixDataSize*/ +#endif +); + +#endif /* PIXMAP_H */ diff --git a/include/Xserver/region.h b/include/Xserver/region.h new file mode 100755 index 0000000..b12de29 --- /dev/null +++ b/include/Xserver/region.h @@ -0,0 +1,54 @@ +/* $XConsortium: region.h,v 1.5 94/04/17 20:25:59 dpw Exp $ */ +/*********************************************************** + +Copyright (c) 1987 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. + + +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/include/Xserver/regionstr.h b/include/Xserver/regionstr.h new file mode 100755 index 0000000..0efd965 --- /dev/null +++ b/include/Xserver/regionstr.h @@ -0,0 +1,409 @@ +/* $XConsortium: regionstr.h,v 1.8 94/04/17 20:26:01 dpw Exp $ */ +/*********************************************************** + +Copyright (c) 1987 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. + + +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 "miscstruct.h" + +/* Return values from RectIn() */ + +#define rgnOUT 0 +#define rgnIN 1 +#define rgnPART 2 + +#define NullRegion ((RegionPtr)0) + +/* + * clip region + */ + +typedef struct _RegData { + long size; + long numRects; +/* BoxRec rects[size]; in memory but not explicitly declared */ +} RegDataRec, *RegDataPtr; + +typedef struct _Region { + BoxRec extents; + RegDataPtr data; +} RegionRec, *RegionPtr; + +extern BoxRec miEmptyBox; +extern RegDataRec miEmptyData; + +#define REGION_NIL(reg) ((reg)->data && !(reg)->data->numRects) +#define REGION_NUM_RECTS(reg) ((reg)->data ? (reg)->data->numRects : 1) +#define REGION_SIZE(reg) ((reg)->data ? (reg)->data->size : 0) +#define REGION_RECTS(reg) ((reg)->data ? (BoxPtr)((reg)->data + 1) \ + : &(reg)->extents) +#define REGION_BOXPTR(reg) ((BoxPtr)((reg)->data + 1)) +#define REGION_BOX(reg,i) (®ION_BOXPTR(reg)[i]) +#define REGION_TOP(reg) REGION_BOX(reg, (reg)->data->numRects) +#define REGION_END(reg) REGION_BOX(reg, (reg)->data->numRects - 1) +#define REGION_SZOF(n) (sizeof(RegDataRec) + ((n) * sizeof(BoxRec))) + +#ifdef NEED_SCREEN_REGIONS + +#define REGION_CREATE(_pScreen, _rect, _size) \ + (*(_pScreen)->RegionCreate)(_rect, _size) + +#define REGION_INIT(_pScreen, _pReg, _rect, _size) \ + (*(_pScreen)->RegionInit)(_pReg, _rect, _size) + +#define REGION_COPY(_pScreen, dst, src) \ + (*(_pScreen)->RegionCopy)(dst, src) + +#define REGION_DESTROY(_pScreen, _pReg) \ + (*(_pScreen)->RegionDestroy)(_pReg) + +#define REGION_UNINIT(_pScreen, _pReg) \ + (*(_pScreen)->RegionUninit)(_pReg) + +#define REGION_INTERSECT(_pScreen, newReg, reg1, reg2) \ + (*(_pScreen)->Intersect)(newReg, reg1, reg2) + +#define REGION_UNION(_pScreen, newReg, reg1, reg2) \ + (*(_pScreen)->Union)(newReg, reg1, reg2) + +#define REGION_SUBTRACT(_pScreen, newReg, reg1, reg2) \ + (*(_pScreen)->Subtract)(newReg, reg1, reg2) + +#define REGION_INVERSE(_pScreen, newReg, reg1, invRect) \ + (*(_pScreen)->Inverse)(newReg, reg1, invRect) + +#define REGION_RESET(_pScreen, _pReg, _pBox) \ + (*(_pScreen)->RegionReset)(_pReg, _pBox) + +#define REGION_TRANSLATE(_pScreen, _pReg, _x, _y) \ + (*(_pScreen)->TranslateRegion)(_pReg, _x, _y) + +#define RECT_IN_REGION(_pScreen, _pReg, prect) \ + (*(_pScreen)->RectIn)(_pReg, prect) + +#define POINT_IN_REGION(_pScreen, _pReg, _x, _y, prect) \ + (*(_pScreen)->PointInRegion)(_pReg, _x, _y, prect) + +#define REGION_NOTEMPTY(_pScreen, _pReg) \ + (*(_pScreen)->RegionNotEmpty)(_pReg) + +#define REGION_EMPTY(_pScreen, _pReg) \ + (*(_pScreen)->RegionEmpty)(_pReg) + +#define REGION_EXTENTS(_pScreen, _pReg) \ + (*(_pScreen)->RegionExtents)(_pReg) + +#define REGION_APPEND(_pScreen, dstrgn, rgn) \ + (*(_pScreen)->RegionAppend)(dstrgn, rgn) + +#define REGION_VALIDATE(_pScreen, badreg, pOverlap) \ + (*(_pScreen)->RegionValidate)(badreg, pOverlap) + +#define BITMAP_TO_REGION(_pScreen, pPix) \ + (*(_pScreen)->BitmapToRegion)(pPix) + +#define RECTS_TO_REGION(_pScreen, nrects, prect, ctype) \ + (*(_pScreen)->RectsToRegion)(nrects, prect, ctype) + +#else /* !NEED_SCREEN_REGIONS */ + +#define REGION_CREATE(_pScreen, _rect, _size) \ + miRegionCreate(_rect, _size) + +#define REGION_COPY(_pScreen, dst, src) \ + miRegionCopy(dst, src) + +#define REGION_DESTROY(_pScreen, _pReg) \ + miRegionDestroy(_pReg) + +#define REGION_INTERSECT(_pScreen, newReg, reg1, reg2) \ + miIntersect(newReg, reg1, reg2) + +#define REGION_UNION(_pScreen, newReg, reg1, reg2) \ + miUnion(newReg, reg1, reg2) + +#define REGION_SUBTRACT(_pScreen, newReg, reg1, reg2) \ + miSubtract(newReg, reg1, reg2) + +#define REGION_INVERSE(_pScreen, newReg, reg1, invRect) \ + miInverse(newReg, reg1, invRect) + +#define REGION_TRANSLATE(_pScreen, _pReg, _x, _y) \ + miTranslateRegion(_pReg, _x, _y) + +#define RECT_IN_REGION(_pScreen, _pReg, prect) \ + miRectIn(_pReg, prect) + +#define POINT_IN_REGION(_pScreen, _pReg, _x, _y, prect) \ + miPointInRegion(_pReg, _x, _y, prect) + +#define REGION_APPEND(_pScreen, dstrgn, rgn) \ + miRegionAppend(dstrgn, rgn) + +#define REGION_VALIDATE(_pScreen, badreg, pOverlap) \ + miRegionValidate(badreg, pOverlap) + +#define BITMAP_TO_REGION(_pScreen, pPix) \ + (*(_pScreen)->BitmapToRegion)(pPix) /* no mi version?! */ + +#define RECTS_TO_REGION(_pScreen, nrects, prect, ctype) \ + miRectsToRegion(nrects, prect, ctype) + +#ifdef DONT_INLINE_REGION_OPS + +#define REGION_INIT(_pScreen, _pReg, _rect, _size) \ + miRegionInit(_pReg, _rect, _size) + +#define REGION_UNINIT(_pScreen, _pReg) \ + miRegionUninit(_pReg) + +#define REGION_RESET(_pScreen, _pReg, _pBox) \ + miRegionReset(_pReg, _pBox) + +#define REGION_NOTEMPTY(_pScreen, _pReg) \ + miRegionNotEmpty(_pReg) + +#define REGION_EMPTY(_pScreen, _pReg) \ + miRegionEmpty(_pReg) + +#define REGION_EXTENTS(_pScreen, _pReg) \ + miRegionExtents(_pReg) + +#else /* inline certain simple region ops for performance */ + +#define REGION_INIT(_pScreen, _pReg, _rect, _size) \ +{ \ + if (_rect) \ + { \ + (_pReg)->extents = *(_rect); \ + (_pReg)->data = (RegDataPtr)NULL; \ + } \ + else \ + { \ + (_pReg)->extents = miEmptyBox; \ + if (((_size) > 1) && ((_pReg)->data = \ + (RegDataPtr)xalloc(REGION_SZOF(_size)))) \ + { \ + (_pReg)->data->size = (_size); \ + (_pReg)->data->numRects = 0; \ + } \ + else \ + (_pReg)->data = &miEmptyData; \ + } \ +} + +#define REGION_UNINIT(_pScreen, _pReg) \ +{ \ + if ((_pReg)->data && (_pReg)->data->size) xfree((_pReg)->data); \ +} + +#define REGION_RESET(_pScreen, _pReg, _pBox) \ +{ \ + (_pReg)->extents = *(_pBox); \ + REGION_UNINIT(_pScreen, _pReg); \ + (_pReg)->data = (RegDataPtr)NULL; \ +} + +#define REGION_NOTEMPTY(_pScreen, _pReg) \ + !REGION_NIL(_pReg) + +#define REGION_EMPTY(_pScreen, _pReg) \ +{ \ + REGION_UNINIT(_pScreen, _pReg); \ + (_pReg)->extents.x2 = (_pReg)->extents.x1; \ + (_pReg)->extents.y2 = (_pReg)->extents.y1; \ + (_pReg)->data = &miEmptyData; \ +} + +#define REGION_EXTENTS(_pScreen, _pReg) \ + &(_pReg)->extents + +#endif /* DONT_INLINE_REGION_OPS */ + +#endif /* NEED_SCREEN_REGIONS */ + +/* moved from mi.h */ + +extern RegionPtr miRegionCreate( +#if NeedFunctionPrototypes + BoxPtr /*rect*/, + int /*size*/ +#endif +); + +extern void miRegionInit( +#if NeedFunctionPrototypes + RegionPtr /*pReg*/, + BoxPtr /*rect*/, + int /*size*/ +#endif +); + +extern void miRegionDestroy( +#if NeedFunctionPrototypes + RegionPtr /*pReg*/ +#endif +); + +extern void miRegionUninit( +#if NeedFunctionPrototypes + RegionPtr /*pReg*/ +#endif +); + +extern Bool miRegionCopy( +#if NeedFunctionPrototypes + RegionPtr /*dst*/, + RegionPtr /*src*/ +#endif +); + +extern Bool miIntersect( +#if NeedFunctionPrototypes + RegionPtr /*newReg*/, + RegionPtr /*reg1*/, + RegionPtr /*reg2*/ +#endif +); + +extern Bool miUnion( +#if NeedFunctionPrototypes + RegionPtr /*newReg*/, + RegionPtr /*reg1*/, + RegionPtr /*reg2*/ +#endif +); + +extern Bool miRegionAppend( +#if NeedFunctionPrototypes + RegionPtr /*dstrgn*/, + RegionPtr /*rgn*/ +#endif +); + +extern Bool miRegionValidate( +#if NeedFunctionPrototypes + RegionPtr /*badreg*/, + Bool * /*pOverlap*/ +#endif +); + +extern RegionPtr miRectsToRegion( +#if NeedFunctionPrototypes + int /*nrects*/, + xRectanglePtr /*prect*/, + int /*ctype*/ +#endif +); + +extern Bool miSubtract( +#if NeedFunctionPrototypes + RegionPtr /*regD*/, + RegionPtr /*regM*/, + RegionPtr /*regS*/ +#endif +); + +extern Bool miInverse( +#if NeedFunctionPrototypes + RegionPtr /*newReg*/, + RegionPtr /*reg1*/, + BoxPtr /*invRect*/ +#endif +); + +extern int miRectIn( +#if NeedFunctionPrototypes + RegionPtr /*region*/, + BoxPtr /*prect*/ +#endif +); + +extern void miTranslateRegion( +#if NeedFunctionPrototypes + RegionPtr /*pReg*/, + int /*x*/, + int /*y*/ +#endif +); + +extern void miRegionReset( +#if NeedFunctionPrototypes + RegionPtr /*pReg*/, + BoxPtr /*pBox*/ +#endif +); + +extern Bool miPointInRegion( +#if NeedFunctionPrototypes + RegionPtr /*pReg*/, + int /*x*/, + int /*y*/, + BoxPtr /*box*/ +#endif +); + +extern Bool miRegionNotEmpty( +#if NeedFunctionPrototypes + RegionPtr /*pReg*/ +#endif +); + +extern void miRegionEmpty( +#if NeedFunctionPrototypes + RegionPtr /*pReg*/ +#endif +); + +extern BoxPtr miRegionExtents( +#if NeedFunctionPrototypes + RegionPtr /*pReg*/ +#endif +); + +#endif /* REGIONSTRUCT_H */ diff --git a/include/Xserver/screenint.h b/include/Xserver/screenint.h new file mode 100755 index 0000000..ebeac39 --- /dev/null +++ b/include/Xserver/screenint.h @@ -0,0 +1,171 @@ +/* $XConsortium: screenint.h /main/6 1996/06/17 10:55:15 mor $ */ +/*********************************************************** + +Copyright (c) 1987 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. + + +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. + +******************************************************************/ +/* $XFree86: xc/programs/Xserver/include/screenint.h,v 1.2 1997/01/14 22:22:40 dawes Exp $ */ +#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( +#if NeedFunctionPrototypes + void +#endif +); + +extern int AllocateScreenPrivateIndex( +#if NeedFunctionPrototypes + void +#endif +); + +extern void ResetWindowPrivates( +#if NeedFunctionPrototypes + void +#endif +); + +extern int AllocateWindowPrivateIndex( +#if NeedFunctionPrototypes + void +#endif +); + +extern Bool AllocateWindowPrivate( +#if NeedFunctionPrototypes + ScreenPtr /* pScreen */, + int /* index */, + unsigned /* amount */ +#endif +); + +extern void ResetGCPrivates( +#if NeedFunctionPrototypes + void +#endif +); + +extern int AllocateGCPrivateIndex( +#if NeedFunctionPrototypes + void +#endif +); + +extern Bool AllocateGCPrivate( +#if NeedFunctionPrototypes + ScreenPtr /* pScreen */, + int /* index */, + unsigned /* amount */ +#endif +); + +extern int AddScreen( +#if NeedFunctionPrototypes + Bool (* /*pfnInit*/)( +#if NeedNestedPrototypes + int /*index*/, + ScreenPtr /*pScreen*/, + int /*argc*/, + char ** /*argv*/ +#endif + ), + int /*argc*/, + char** /*argv*/ +#endif +); + +#ifdef PIXPRIV + +extern void ResetPixmapPrivates( +#if NeedFunctionPrototypes + void +#endif +); + +extern int AllocatePixmapPrivateIndex( +#if NeedFunctionPrototypes + void +#endif +); + +extern Bool AllocatePixmapPrivate( +#if NeedFunctionPrototypes + ScreenPtr /* pScreen */, + int /* index */, + unsigned /* amount */ +#endif +); + +#endif /* PIXPRIV */ + +extern void ResetColormapPrivates( +#if NeedFunctionPrototypes + void +#endif +); + + +typedef struct _ColormapRec *ColormapPtr; +typedef int (*InitCmapPrivFunc)( +#if NeedNestedPrototypes + ColormapPtr +#endif +); + +extern int AllocateColormapPrivateIndex( +#if NeedFunctionPrototypes + InitCmapPrivFunc /* initPrivFunc */ +#endif +); + +#endif /* SCREENINT_H */ diff --git a/include/Xserver/scrnintstr.h b/include/Xserver/scrnintstr.h new file mode 100755 index 0000000..c770ecf --- /dev/null +++ b/include/Xserver/scrnintstr.h @@ -0,0 +1,934 @@ +/* $XConsortium: scrnintstr.h /main/32 1996/09/28 17:14:32 rws $ */ +/*********************************************************** + +Copyright (c) 1987 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. + + +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 "miscstruct.h" +#include "region.h" +#include "pixmap.h" +#include "gc.h" +#include "colormap.h" +#include "cursor.h" +#include "validate.h" +#include "window.h" +#include "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 pointer so that code that + * needs to declare a screen function pointer (e.g. in a screen private + * or as a local variable) can easily do so and retain full type checking. + */ + +typedef Bool (* CloseScreenProcPtr)( +#if NeedNestedPrototypes + int /*index*/, + ScreenPtr /*pScreen*/ +#endif +); + +typedef void (* QueryBestSizeProcPtr)( +#if NeedNestedPrototypes + int /*class*/, + unsigned short * /*pwidth*/, + unsigned short * /*pheight*/, + ScreenPtr /*pScreen*/ +#endif +); + +typedef Bool (* SaveScreenProcPtr)( +#if NeedNestedPrototypes + ScreenPtr /*pScreen*/, + int /*on*/ +#endif +); + +typedef void (* GetImageProcPtr)( +#if NeedNestedPrototypes + DrawablePtr /*pDrawable*/, + int /*sx*/, + int /*sy*/, + int /*w*/, + int /*h*/, + unsigned int /*format*/, + unsigned long /*planeMask*/, + char * /*pdstLine*/ +#endif +); + +typedef void (* GetSpansProcPtr)( +#if NeedNestedPrototypes + DrawablePtr /*pDrawable*/, + int /*wMax*/, + DDXPointPtr /*ppt*/, + int* /*pwidth*/, + int /*nspans*/, + char * /*pdstStart*/ +#endif +); + +typedef void (* PointerNonInterestBoxProcPtr)( +#if NeedNestedPrototypes + ScreenPtr /*pScreen*/, + BoxPtr /*pBox*/ +#endif +); + +typedef void (* SourceValidateProcPtr)( +#if NeedNestedPrototypes + DrawablePtr /*pDrawable*/, + int /*x*/, + int /*y*/, + int /*width*/, + int /*height*/ +#endif +); + +typedef Bool (* CreateWindowProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pWindow*/ +#endif +); + +typedef Bool (* DestroyWindowProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pWindow*/ +#endif +); + +typedef Bool (* PositionWindowProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pWindow*/, + int /*x*/, + int /*y*/ +#endif +); + +typedef Bool (* ChangeWindowAttributesProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pWindow*/, + unsigned long /*mask*/ +#endif +); + +typedef Bool (* RealizeWindowProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pWindow*/ +#endif +); + +typedef Bool (* UnrealizeWindowProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pWindow*/ +#endif +); + +typedef int (* ValidateTreeProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pParent*/, + X11WindowPtr /*pChild*/, + VTKind /*kind*/ +#endif +); + +typedef void (* PostValidateTreeProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pParent*/, + X11WindowPtr /*pChild*/, + VTKind /*kind*/ +#endif +); + +typedef void (* WindowExposuresProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pWindow*/, + RegionPtr /*prgn*/, + RegionPtr /*other_exposed*/ +#endif +); + +typedef void (* PaintWindowBackgroundProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pWindow*/, + RegionPtr /*pRegion*/, + int /*what*/ +#endif +); + +typedef void (* PaintWindowBorderProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pWindow*/, + RegionPtr /*pRegion*/, + int /*what*/ +#endif +); + +typedef void (* CopyWindowProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pWindow*/, + DDXPointRec /*ptOldOrg*/, + RegionPtr /*prgnSrc*/ +#endif +); + +typedef void (* ClearToBackgroundProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pWindow*/, + int /*x*/, + int /*y*/, + int /*w*/, + int /*h*/, + Bool /*generateExposures*/ +#endif +); + +typedef void (* ClipNotifyProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pWindow*/, + int /*dx*/, + int /*dy*/ +#endif +); + +typedef PixmapPtr (* CreatePixmapProcPtr)( +#if NeedNestedPrototypes + ScreenPtr /*pScreen*/, + int /*width*/, + int /*height*/, + int /*depth*/ +#endif +); + +typedef Bool (* DestroyPixmapProcPtr)( +#if NeedNestedPrototypes + PixmapPtr /*pPixmap*/ +#endif +); + +typedef void (* SaveDoomedAreasProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pWindow*/, + RegionPtr /*prgnSave*/, + int /*xorg*/, + int /*yorg*/ +#endif +); + +typedef RegionPtr (* RestoreAreasProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pWindow*/, + RegionPtr /*prgnRestore*/ +#endif +); + +typedef void (* ExposeCopyProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pSrc*/, + DrawablePtr /*pDst*/, + GCPtr /*pGC*/, + RegionPtr /*prgnExposed*/, + int /*srcx*/, + int /*srcy*/, + int /*dstx*/, + int /*dsty*/, + unsigned long /*plane*/ +#endif +); + +typedef RegionPtr (* TranslateBackingStoreProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pWindow*/, + int /*windx*/, + int /*windy*/, + RegionPtr /*oldClip*/, + int /*oldx*/, + int /*oldy*/ +#endif +); + +typedef RegionPtr (* ClearBackingStoreProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pWindow*/, + int /*x*/, + int /*y*/, + int /*w*/, + int /*h*/, + Bool /*generateExposures*/ +#endif +); + +typedef void (* DrawGuaranteeProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pWindow*/, + GCPtr /*pGC*/, + int /*guarantee*/ +#endif +); + +typedef Bool (* RealizeFontProcPtr)( +#if NeedNestedPrototypes + ScreenPtr /*pScreen*/, + FontPtr /*pFont*/ +#endif +); + +typedef Bool (* UnrealizeFontProcPtr)( +#if NeedNestedPrototypes + ScreenPtr /*pScreen*/, + FontPtr /*pFont*/ +#endif +); + +typedef void (* ConstrainCursorProcPtr)( +#if NeedNestedPrototypes + ScreenPtr /*pScreen*/, + BoxPtr /*pBox*/ +#endif +); + +typedef void (* CursorLimitsProcPtr)( +#if NeedNestedPrototypes + ScreenPtr /*pScreen*/, + CursorPtr /*pCursor*/, + BoxPtr /*pHotBox*/, + BoxPtr /*pTopLeftBox*/ +#endif +); + +typedef Bool (* DisplayCursorProcPtr)( +#if NeedNestedPrototypes + ScreenPtr /*pScreen*/, + CursorPtr /*pCursor*/ +#endif +); + +typedef Bool (* RealizeCursorProcPtr)( +#if NeedNestedPrototypes + ScreenPtr /*pScreen*/, + CursorPtr /*pCursor*/ +#endif +); + +typedef Bool (* UnrealizeCursorProcPtr)( +#if NeedNestedPrototypes + ScreenPtr /*pScreen*/, + CursorPtr /*pCursor*/ +#endif +); + +typedef void (* RecolorCursorProcPtr)( +#if NeedNestedPrototypes + ScreenPtr /*pScreen*/, + CursorPtr /*pCursor*/, + Bool /*displayed*/ +#endif +); + +typedef Bool (* SetCursorPositionProcPtr)( +#if NeedNestedPrototypes + ScreenPtr /*pScreen*/, + int /*x*/, + int /*y*/, + Bool /*generateEvent*/ +#endif +); + +typedef Bool (* CreateGCProcPtr)( +#if NeedNestedPrototypes + GCPtr /*pGC*/ +#endif +); + +typedef Bool (* CreateColormapProcPtr)( +#if NeedNestedPrototypes + ColormapPtr /*pColormap*/ +#endif +); + +typedef void (* DestroyColormapProcPtr)( +#if NeedNestedPrototypes + ColormapPtr /*pColormap*/ +#endif +); + +typedef void (* InstallColormapProcPtr)( +#if NeedNestedPrototypes + ColormapPtr /*pColormap*/ +#endif +); + +typedef void (* UninstallColormapProcPtr)( +#if NeedNestedPrototypes + ColormapPtr /*pColormap*/ +#endif +); + +typedef int (* ListInstalledColormapsProcPtr) ( +#if NeedNestedPrototypes + ScreenPtr /*pScreen*/, + XID* /*pmaps */ +#endif +); + +typedef void (* StoreColorsProcPtr)( +#if NeedNestedPrototypes + ColormapPtr /*pColormap*/, + int /*ndef*/, + xColorItem * /*pdef*/ +#endif +); + +typedef void (* ResolveColorProcPtr)( +#if NeedNestedPrototypes + unsigned short* /*pred*/, + unsigned short* /*pgreen*/, + unsigned short* /*pblue*/, + VisualPtr /*pVisual*/ +#endif +); + +typedef RegionPtr (* RegionCreateProcPtr)( +#if NeedNestedPrototypes + BoxPtr /*rect*/, + int /*size*/ +#endif +); + +typedef void (* RegionInitProcPtr)( +#if NeedNestedPrototypes + RegionPtr /*pReg*/, + BoxPtr /*rect*/, + int /*size*/ +#endif +); + +typedef Bool (* RegionCopyProcPtr)( +#if NeedNestedPrototypes + RegionPtr /*dst*/, + RegionPtr /*src*/ +#endif +); + +typedef void (* RegionDestroyProcPtr)( +#if NeedNestedPrototypes + RegionPtr /*pReg*/ +#endif +); + +typedef void (* RegionUninitProcPtr)( +#if NeedNestedPrototypes + RegionPtr /*pReg*/ +#endif +); + +typedef Bool (* IntersectProcPtr)( +#if NeedNestedPrototypes + RegionPtr /*newReg*/, + RegionPtr /*reg1*/, + RegionPtr /*reg2*/ +#endif +); + +typedef Bool (* UnionProcPtr)( +#if NeedNestedPrototypes + RegionPtr /*newReg*/, + RegionPtr /*reg1*/, + RegionPtr /*reg2*/ +#endif +); + +typedef Bool (* SubtractProcPtr)( +#if NeedNestedPrototypes + RegionPtr /*regD*/, + RegionPtr /*regM*/, + RegionPtr /*regS*/ +#endif +); + +typedef Bool (* InverseProcPtr)( +#if NeedNestedPrototypes + RegionPtr /*newReg*/, + RegionPtr /*reg1*/, + BoxPtr /*invRect*/ +#endif +); + +typedef void (* RegionResetProcPtr)( +#if NeedNestedPrototypes + RegionPtr /*pReg*/, + BoxPtr /*pBox*/ +#endif +); + +typedef void (* TranslateRegionProcPtr)( +#if NeedNestedPrototypes + RegionPtr /*pReg*/, + int /*x*/, + int /*y*/ +#endif +); + +typedef int (* RectInProcPtr)( +#if NeedNestedPrototypes + RegionPtr /*region*/, + BoxPtr /*prect*/ +#endif +); + +typedef Bool (* PointInRegionProcPtr)( +#if NeedNestedPrototypes + RegionPtr /*pReg*/, + int /*x*/, + int /*y*/, + BoxPtr /*box*/ +#endif +); + +typedef Bool (* RegionNotEmptyProcPtr)( +#if NeedNestedPrototypes + RegionPtr /*pReg*/ +#endif +); + +typedef void (* RegionEmptyProcPtr)( +#if NeedNestedPrototypes + RegionPtr /*pReg*/ +#endif +); + +typedef BoxPtr (* RegionExtentsProcPtr)( +#if NeedNestedPrototypes + RegionPtr /*pReg*/ +#endif +); + +typedef Bool (* RegionAppendProcPtr)( +#if NeedNestedPrototypes + RegionPtr /*dstrgn*/, + RegionPtr /*rgn*/ +#endif +); + +typedef Bool (* RegionValidateProcPtr)( +#if NeedNestedPrototypes + RegionPtr /*badreg*/, + Bool* /*pOverlap*/ +#endif +); + +typedef RegionPtr (* BitmapToRegionProcPtr)( +#if NeedNestedPrototypes + PixmapPtr /*pPix*/ +#endif +); + +typedef RegionPtr (* RectsToRegionProcPtr)( +#if NeedNestedPrototypes + int /*nrects*/, + xRectangle* /*prect*/, + int /*ctype*/ +#endif +); + +typedef void (* SendGraphicsExposeProcPtr)( +#if NeedNestedPrototypes + ClientPtr /*client*/, + RegionPtr /*pRgn*/, + XID /*drawable*/, + int /*major*/, + int /*minor*/ +#endif +); + +typedef void (* ScreenBlockHandlerProcPtr)( +#if NeedNestedPrototypes + int /*screenNum*/, + pointer /*blockData*/, + struct timeval ** /*pTimeout*/, + pointer /*pReadmask*/ +#endif +); + +typedef void (* ScreenWakeupHandlerProcPtr)( +#if NeedNestedPrototypes + int /*screenNum*/, + pointer /*wakeupData*/, + unsigned long /*result*/, + pointer /*pReadMask*/ +#endif +); + +typedef Bool (* CreateScreenResourcesProcPtr)( +#if NeedNestedPrototypes + ScreenPtr /*pScreen*/ +#endif +); + +typedef Bool (* ModifyPixmapHeaderProcPtr)( +#if NeedNestedPrototypes + PixmapPtr /*pPixmap*/, + int /*width*/, + int /*height*/, + int /*depth*/, + int /*bitsPerPixel*/, + int /*devKind*/, + pointer /*pPixData*/ +#endif +); + +typedef void (* MarkWindowProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pWin*/ +#endif +); + +typedef Bool (* MarkOverlappedWindowsProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*parent*/, + X11WindowPtr /*firstChild*/, + X11WindowPtr * /*pLayerWin*/ +#endif +); + +typedef Bool (* ChangeSaveUnderProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pLayerWin*/, + X11WindowPtr /*firstChild*/ +#endif +); + +typedef void (* PostChangeSaveUnderProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pLayerWin*/, + X11WindowPtr /*firstChild*/ +#endif +); + +typedef void (* MoveWindowProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pWin*/, + int /*x*/, + int /*y*/, + X11WindowPtr /*pSib*/, + VTKind /*kind*/ +#endif +); + +typedef void (* ResizeWindowProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pWin*/, + int /*x*/, + int /*y*/, + unsigned int /*w*/, + unsigned int /*h*/, + X11WindowPtr /*pSib*/ +#endif +); + +typedef X11WindowPtr (* GetLayerWindowProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pWin*/ +#endif +); + +typedef void (* HandleExposuresProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pWin*/ +#endif +); + +typedef void (* ReparentWindowProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pWin*/, + X11WindowPtr /*pPriorParent*/ +#endif +); + +#ifdef SHAPE +typedef void (* SetShapeProcPtr)( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/ +#endif +); +#endif /* SHAPE */ + +typedef void (* ChangeBorderWidthProcPtr)( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/, + unsigned int /*width*/ +#endif +); + +typedef void (* MarkUnrealizedWindowProcPtr)( +#if NeedFunctionPrototypes + X11WindowPtr /*pChild*/, + X11WindowPtr /*pWin*/, + Bool /*fromConfigure*/ +#endif +); + +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]; + pointer devPrivate; + short numVisuals; + VisualPtr visuals; + 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; + + /* Pixmap procedures */ + + CreatePixmapProcPtr CreatePixmap; + DestroyPixmapProcPtr DestroyPixmap; + + /* Backing store procedures */ + + SaveDoomedAreasProcPtr SaveDoomedAreas; + RestoreAreasProcPtr RestoreAreas; + ExposeCopyProcPtr ExposeCopy; + TranslateBackingStoreProcPtr TranslateBackingStore; + ClearBackingStoreProcPtr ClearBackingStore; + DrawGuaranteeProcPtr DrawGuarantee; + + /* Font procedures */ + + RealizeFontProcPtr RealizeFont; + UnrealizeFontProcPtr UnrealizeFont; + + /* Cursor Procedures */ + + ConstrainCursorProcPtr ConstrainCursor; + 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 */ + + 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; + RegionEmptyProcPtr RegionEmpty; + RegionExtentsProcPtr RegionExtents; + RegionAppendProcPtr RegionAppend; + RegionValidateProcPtr RegionValidate; + BitmapToRegionProcPtr BitmapToRegion; + RectsToRegionProcPtr RectsToRegion; + SendGraphicsExposeProcPtr SendGraphicsExpose; + + /* os layer procedures */ + + ScreenBlockHandlerProcPtr BlockHandler; + ScreenWakeupHandlerProcPtr WakeupHandler; + + pointer blockData; + pointer wakeupData; + + /* anybody can get a piece of this array */ + DevUnion *devPrivates; + + CreateScreenResourcesProcPtr CreateScreenResources; + ModifyPixmapHeaderProcPtr ModifyPixmapHeader; + + PixmapPtr pScratchPixmap; /* scratch pixmap "pool" */ + +#ifdef PIXPRIV + int PixmapPrivateLen; + unsigned *PixmapPrivateSizes; + unsigned 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; + +} ScreenRec; + +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( +#if NeedFunctionPrototypes + ScreenInfo * /*pScreenInfo*/, + int /*argc*/, + char ** /*argv*/ +#endif +); + +#endif /* SCREENINTSTRUCT_H */ diff --git a/include/Xserver/validate.h b/include/Xserver/validate.h new file mode 100755 index 0000000..756ad89 --- /dev/null +++ b/include/Xserver/validate.h @@ -0,0 +1,42 @@ +/* $XConsortium: validate.h,v 5.4 94/04/17 20:26:11 dpw Exp $ */ + +/* + +Copyright (c) 1989 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 VALIDATE_H +#define VALIDATE_H + +#include "miscstruct.h" +#include "regionstr.h" + +typedef enum { VTOther, VTStack, VTMove, VTUnmap, VTMap } 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/include/Xserver/window.h b/include/Xserver/window.h new file mode 100755 index 0000000..2919e23 --- /dev/null +++ b/include/Xserver/window.h @@ -0,0 +1,351 @@ +/* $XConsortium: window.h /main/8 1996/03/21 13:35:33 mor $ */ +/*********************************************************** + +Copyright (c) 1987 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. + + +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 "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 ((X11WindowPtr) 0) + +typedef struct _BackingStore *BackingStorePtr; +typedef struct _Window *X11WindowPtr; /* conflict with CoreGraphics */ + +typedef int (*VisitWindowProcPtr)( +#if NeedNestedPrototypes + X11WindowPtr /*pWin*/, + pointer /*data*/ +#endif +); + +extern int TraverseTree( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/, + VisitWindowProcPtr /*func*/, + pointer /*data*/ +#endif +); + +extern int WalkTree( +#if NeedFunctionPrototypes + ScreenPtr /*pScreen*/, + VisitWindowProcPtr /*func*/, + pointer /*data*/ +#endif +); + +extern X11WindowPtr AllocateWindow( +#if NeedFunctionPrototypes + ScreenPtr /*pScreen*/ +#endif +); + +extern Bool CreateRootWindow( +#if NeedFunctionPrototypes + ScreenPtr /*pScreen*/ +#endif +); + +extern void InitRootWindow( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/ +#endif +); + +extern void ClippedRegionFromBox( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/, + RegionPtr /*Rgn*/, + int /*x*/, + int /*y*/, + int /*w*/, + int /*h*/ +#endif +); + +extern X11WindowPtr RealChildHead( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/ +#endif +); + +extern X11WindowPtr CreateWindow( +#if NeedFunctionPrototypes + Window /*wid*/, + X11WindowPtr /*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*/ +#endif +); + +extern int DeleteWindow( +#if NeedFunctionPrototypes + pointer /*pWin*/, + XID /*wid*/ +#endif +); + +extern void DestroySubwindows( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/, + ClientPtr /*client*/ +#endif +); + +extern int X11ChangeWindowAttributes( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/, + Mask /*vmask*/, + XID* /*vlist*/, + ClientPtr /*client*/ +#endif +); + +extern void X11GetWindowAttributes( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/, + ClientPtr /*client*/, + xGetWindowAttributesReply* /* wa */ +#endif +); + +extern RegionPtr CreateUnclippedWinSize( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/ +#endif +); + +extern void GravityTranslate( +#if NeedFunctionPrototypes + int /*x*/, + int /*y*/, + int /*oldx*/, + int /*oldy*/, + int /*dw*/, + int /*dh*/, + unsigned /*gravity*/, + int* /*destx*/, + int* /*desty*/ +#endif +); + +extern int ConfigureWindow( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/, + Mask /*mask*/, + XID* /*vlist*/, + ClientPtr /*client*/ +#endif +); + +extern int CirculateWindow( +#if NeedFunctionPrototypes + X11WindowPtr /*pParent*/, + int /*direction*/, + ClientPtr /*client*/ +#endif +); + +extern int ReparentWindow( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/, + X11WindowPtr /*pParent*/, + int /*x*/, + int /*y*/, + ClientPtr /*client*/ +#endif +); + +extern int MapWindow( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/, + ClientPtr /*client*/ +#endif +); + +extern void MapSubwindows( +#if NeedFunctionPrototypes + X11WindowPtr /*pParent*/, + ClientPtr /*client*/ +#endif +); + +extern int UnmapWindow( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/, + Bool /*fromConfigure*/ +#endif +); + +extern void UnmapSubwindows( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/ +#endif +); + +extern void HandleSaveSet( +#if NeedFunctionPrototypes + ClientPtr /*client*/ +#endif +); + +extern Bool VisibleBoundingBoxFromPoint( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/, + int /*x*/, + int /*y*/, + BoxPtr /*box*/ +#endif +); + +extern Bool PointInWindowIsVisible( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/, + int /*x*/, + int /*y*/ +#endif +); + +extern RegionPtr NotClippedByChildren( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/ +#endif +); + +extern void SendVisibilityNotify( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/ +#endif +); + +extern void SaveScreens( +#if NeedFunctionPrototypes + int /*on*/, + int /*mode*/ +#endif +); + +extern X11WindowPtr FindWindowWithOptional( +#if NeedFunctionPrototypes + X11WindowPtr /*w*/ +#endif +); + +extern void CheckWindowOptionalNeed( +#if NeedFunctionPrototypes + X11WindowPtr /*w*/ +#endif +); + +extern Bool MakeWindowOptional( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/ +#endif +); + +extern void DisposeWindowOptional( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/ +#endif +); + +extern X11WindowPtr MoveWindowInStack( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/, + X11WindowPtr /*pNextSib*/ +#endif +); + +void SetWinSize( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/ +#endif +); + +void SetBorderSize( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/ +#endif +); + +void ResizeChildrenWinSize( +#if NeedFunctionPrototypes + X11WindowPtr /*pWin*/, + int /*dx*/, + int /*dy*/, + int /*dw*/, + int /*dh*/ +#endif +); + +#endif /* WINDOW_H */ diff --git a/kbdptr.c b/kbdptr.c new file mode 100644 index 0000000..8c2d678 --- /dev/null +++ b/kbdptr.c @@ -0,0 +1,31 @@ +/* + * kbdptr.c - deal with keyboard and pointer device over TCP & UDP. + * + * + */ + +/* + * OSXvnc Copyright (C) 2001 Dan McGuirk . + * Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge. + * All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include +#include +#include "rfb.h" + diff --git a/libvncauth/Imakefile b/libvncauth/Imakefile new file mode 100644 index 0000000..2e100a6 --- /dev/null +++ b/libvncauth/Imakefile @@ -0,0 +1,16 @@ + +#ifdef SunArchitecture +CC = gcc +CCOPTIONS = +CDEBUGFLAGS = -O2 +#endif + +SRCS = vncauth.c d3des.c + +OBJS = vncauth.o d3des.o + +INCLUDES = -I. -I../include + +NormalLibraryTarget(vncauth,$(OBJS)) + +DependTarget() diff --git a/libvncauth/Makefile b/libvncauth/Makefile new file mode 100644 index 0000000..2781222 --- /dev/null +++ b/libvncauth/Makefile @@ -0,0 +1,9 @@ +OBJS=vncauth.o d3des.o + +CFLAGS=-I. + +all: libvncauth.a + +libvncauth.a: $(OBJS) + $(AR) clq $@ $(OBJS) + diff --git a/libvncauth/d3des.c b/libvncauth/d3des.c new file mode 100644 index 0000000..8a358ce --- /dev/null +++ b/libvncauth/d3des.c @@ -0,0 +1,440 @@ +/* + * This is D3DES (V5.09) by Richard Outerbridge with the double and + * triple-length support removed for use in VNC. Also the bytebit[] array + * has been reversed so that the most significant bit in each byte of the + * key is ignored, not the least significant. + * + * These changes are: + * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* D3DES (V5.09) - + * + * A portable, public domain, version of the Data Encryption Standard. + * + * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge. + * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation + * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis + * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau, + * for humouring me on. + * + * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge. + * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992. + */ + +#include "d3des.h" + +static void scrunch(unsigned char *, unsigned long *); +static void unscrun(unsigned long *, unsigned char *); +static void desfunc(unsigned long *, unsigned long *); +static void cookey(unsigned long *); + +static unsigned long KnL[32] = { 0L }; +static unsigned long KnR[32] = { 0L }; +static unsigned long Kn3[32] = { 0L }; +static unsigned char Df_Key[24] = { + 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, + 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10, + 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 }; + +static unsigned short bytebit[8] = { + 01, 02, 04, 010, 020, 040, 0100, 0200 }; + +static unsigned long bigbyte[24] = { + 0x800000L, 0x400000L, 0x200000L, 0x100000L, + 0x80000L, 0x40000L, 0x20000L, 0x10000L, + 0x8000L, 0x4000L, 0x2000L, 0x1000L, + 0x800L, 0x400L, 0x200L, 0x100L, + 0x80L, 0x40L, 0x20L, 0x10L, + 0x8L, 0x4L, 0x2L, 0x1L }; + +/* Use the key schedule specified in the Standard (ANSI X3.92-1981). */ + +static unsigned char pc1[56] = { + 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, + 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, + 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, + 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 }; + +static unsigned char totrot[16] = { + 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 }; + +static unsigned char pc2[48] = { + 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, + 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, + 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, + 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 }; + +void deskey(key, edf) /* Thanks to James Gillogly & Phil Karn! */ +unsigned char *key; +int edf; +{ + register int i, j, l, m, n; + unsigned char pc1m[56], pcr[56]; + unsigned long kn[32]; + + for ( j = 0; j < 56; j++ ) { + l = pc1[j]; + m = l & 07; + pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0; + } + for( i = 0; i < 16; i++ ) { + if( edf == DE1 ) m = (15 - i) << 1; + else m = i << 1; + n = m + 1; + kn[m] = kn[n] = 0L; + for( j = 0; j < 28; j++ ) { + l = j + totrot[i]; + if( l < 28 ) pcr[j] = pc1m[l]; + else pcr[j] = pc1m[l - 28]; + } + for( j = 28; j < 56; j++ ) { + l = j + totrot[i]; + if( l < 56 ) pcr[j] = pc1m[l]; + else pcr[j] = pc1m[l - 28]; + } + for( j = 0; j < 24; j++ ) { + if( pcr[pc2[j]] ) kn[m] |= bigbyte[j]; + if( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j]; + } + } + cookey(kn); + return; + } + +static void cookey(raw1) +register unsigned long *raw1; +{ + register unsigned long *cook, *raw0; + unsigned long dough[32]; + register int i; + + cook = dough; + for( i = 0; i < 16; i++, raw1++ ) { + raw0 = raw1++; + *cook = (*raw0 & 0x00fc0000L) << 6; + *cook |= (*raw0 & 0x00000fc0L) << 10; + *cook |= (*raw1 & 0x00fc0000L) >> 10; + *cook++ |= (*raw1 & 0x00000fc0L) >> 6; + *cook = (*raw0 & 0x0003f000L) << 12; + *cook |= (*raw0 & 0x0000003fL) << 16; + *cook |= (*raw1 & 0x0003f000L) >> 4; + *cook++ |= (*raw1 & 0x0000003fL); + } + usekey(dough); + return; + } + +void cpkey(into) +register unsigned long *into; +{ + register unsigned long *from, *endp; + + from = KnL, endp = &KnL[32]; + while( from < endp ) *into++ = *from++; + return; + } + +void usekey(from) +register unsigned long *from; +{ + register unsigned long *to, *endp; + + to = KnL, endp = &KnL[32]; + while( to < endp ) *to++ = *from++; + return; + } + +void des(inblock, outblock) +unsigned char *inblock, *outblock; +{ + unsigned long work[2]; + + scrunch(inblock, work); + desfunc(work, KnL); + unscrun(work, outblock); + return; + } + +static void scrunch(outof, into) +register unsigned char *outof; +register unsigned long *into; +{ + *into = (*outof++ & 0xffL) << 24; + *into |= (*outof++ & 0xffL) << 16; + *into |= (*outof++ & 0xffL) << 8; + *into++ |= (*outof++ & 0xffL); + *into = (*outof++ & 0xffL) << 24; + *into |= (*outof++ & 0xffL) << 16; + *into |= (*outof++ & 0xffL) << 8; + *into |= (*outof & 0xffL); + return; + } + +static void unscrun(outof, into) +register unsigned long *outof; +register unsigned char *into; +{ + *into++ = (*outof >> 24) & 0xffL; + *into++ = (*outof >> 16) & 0xffL; + *into++ = (*outof >> 8) & 0xffL; + *into++ = *outof++ & 0xffL; + *into++ = (*outof >> 24) & 0xffL; + *into++ = (*outof >> 16) & 0xffL; + *into++ = (*outof >> 8) & 0xffL; + *into = *outof & 0xffL; + return; + } + +static unsigned long SP1[64] = { + 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L, + 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L, + 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L, + 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L, + 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L, + 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L, + 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L, + 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L, + 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L, + 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L, + 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L, + 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L, + 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L, + 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L, + 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L, + 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L }; + +static unsigned long SP2[64] = { + 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L, + 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L, + 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L, + 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L, + 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L, + 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L, + 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L, + 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L, + 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L, + 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L, + 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L, + 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L, + 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L, + 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L, + 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L, + 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L }; + +static unsigned long SP3[64] = { + 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L, + 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L, + 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L, + 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L, + 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L, + 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L, + 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L, + 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L, + 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L, + 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L, + 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L, + 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L, + 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L, + 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L, + 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L, + 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L }; + +static unsigned long SP4[64] = { + 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, + 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L, + 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L, + 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L, + 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L, + 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L, + 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L, + 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L, + 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L, + 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L, + 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L, + 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, + 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L, + 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L, + 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L, + 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L }; + +static unsigned long SP5[64] = { + 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L, + 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L, + 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L, + 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L, + 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L, + 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L, + 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L, + 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L, + 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L, + 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L, + 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L, + 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L, + 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L, + 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L, + 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L, + 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L }; + +static unsigned long SP6[64] = { + 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L, + 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L, + 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L, + 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L, + 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L, + 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L, + 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L, + 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L, + 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L, + 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L, + 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L, + 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L, + 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L, + 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L, + 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L, + 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L }; + +static unsigned long SP7[64] = { + 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L, + 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L, + 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L, + 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L, + 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L, + 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L, + 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L, + 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L, + 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L, + 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L, + 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L, + 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L, + 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L, + 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L, + 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L, + 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L }; + +static unsigned long SP8[64] = { + 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L, + 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L, + 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L, + 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L, + 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L, + 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L, + 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L, + 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L, + 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L, + 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L, + 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L, + 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L, + 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L, + 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L, + 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L, + 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L }; + +static void desfunc(block, keys) +register unsigned long *block, *keys; +{ + register unsigned long fval, work, right, leftt; + register int round; + + leftt = block[0]; + right = block[1]; + work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL; + right ^= work; + leftt ^= (work << 4); + work = ((leftt >> 16) ^ right) & 0x0000ffffL; + right ^= work; + leftt ^= (work << 16); + work = ((right >> 2) ^ leftt) & 0x33333333L; + leftt ^= work; + right ^= (work << 2); + work = ((right >> 8) ^ leftt) & 0x00ff00ffL; + leftt ^= work; + right ^= (work << 8); + right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL; + work = (leftt ^ right) & 0xaaaaaaaaL; + leftt ^= work; + right ^= work; + leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL; + + for( round = 0; round < 8; round++ ) { + work = (right << 28) | (right >> 4); + work ^= *keys++; + fval = SP7[ work & 0x3fL]; + fval |= SP5[(work >> 8) & 0x3fL]; + fval |= SP3[(work >> 16) & 0x3fL]; + fval |= SP1[(work >> 24) & 0x3fL]; + work = right ^ *keys++; + fval |= SP8[ work & 0x3fL]; + fval |= SP6[(work >> 8) & 0x3fL]; + fval |= SP4[(work >> 16) & 0x3fL]; + fval |= SP2[(work >> 24) & 0x3fL]; + leftt ^= fval; + work = (leftt << 28) | (leftt >> 4); + work ^= *keys++; + fval = SP7[ work & 0x3fL]; + fval |= SP5[(work >> 8) & 0x3fL]; + fval |= SP3[(work >> 16) & 0x3fL]; + fval |= SP1[(work >> 24) & 0x3fL]; + work = leftt ^ *keys++; + fval |= SP8[ work & 0x3fL]; + fval |= SP6[(work >> 8) & 0x3fL]; + fval |= SP4[(work >> 16) & 0x3fL]; + fval |= SP2[(work >> 24) & 0x3fL]; + right ^= fval; + } + + right = (right << 31) | (right >> 1); + work = (leftt ^ right) & 0xaaaaaaaaL; + leftt ^= work; + right ^= work; + leftt = (leftt << 31) | (leftt >> 1); + work = ((leftt >> 8) ^ right) & 0x00ff00ffL; + right ^= work; + leftt ^= (work << 8); + work = ((leftt >> 2) ^ right) & 0x33333333L; + right ^= work; + leftt ^= (work << 2); + work = ((right >> 16) ^ leftt) & 0x0000ffffL; + leftt ^= work; + right ^= (work << 16); + work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL; + leftt ^= work; + right ^= (work << 4); + *block++ = right; + *block = leftt; + return; + } + +/* Validation sets: + * + * Single-length key, single-length plaintext - + * Key : 0123 4567 89ab cdef + * Plain : 0123 4567 89ab cde7 + * Cipher : c957 4425 6a5e d31d + * + * Double-length key, single-length plaintext - + * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 + * Plain : 0123 4567 89ab cde7 + * Cipher : 7f1d 0a77 826b 8aff + * + * Double-length key, double-length plaintext - + * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 + * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff + * Cipher : 27a0 8440 406a df60 278f 47cf 42d6 15d7 + * + * Triple-length key, single-length plaintext - + * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567 + * Plain : 0123 4567 89ab cde7 + * Cipher : de0b 7c06 ae5e 0ed5 + * + * Triple-length key, double-length plaintext - + * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567 + * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff + * Cipher : ad0d 1b30 ac17 cf07 0ed1 1c63 81e4 4de5 + * + * d3des V5.0a rwo 9208.07 18:44 Graven Imagery + **********************************************************************/ diff --git a/libvncauth/d3des.h b/libvncauth/d3des.h new file mode 100644 index 0000000..ea3da44 --- /dev/null +++ b/libvncauth/d3des.h @@ -0,0 +1,51 @@ +/* + * This is D3DES (V5.09) by Richard Outerbridge with the double and + * triple-length support removed for use in VNC. + * + * These changes are: + * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* d3des.h - + * + * Headers and defines for d3des.c + * Graven Imagery, 1992. + * + * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge + * (GEnie : OUTER; CIS : [71755,204]) + */ + +#define EN0 0 /* MODE == encrypt */ +#define DE1 1 /* MODE == decrypt */ + +extern void deskey(unsigned char *, int); +/* hexkey[8] MODE + * Sets the internal key register according to the hexadecimal + * key contained in the 8 bytes of hexkey, according to the DES, + * for encryption or decryption according to MODE. + */ + +extern void usekey(unsigned long *); +/* cookedkey[32] + * Loads the internal key register with the data in cookedkey. + */ + +extern void cpkey(unsigned long *); +/* cookedkey[32] + * Copies the contents of the internal key register into the storage + * located at &cookedkey[0]. + */ + +extern void des(unsigned char *, unsigned char *); +/* from[8] to[8] + * Encrypts/Decrypts (according to the key currently loaded in the + * internal key register) one block of eight bytes at address 'from' + * into the block at address 'to'. They can be the same. + */ + +/* d3des.h V5.09 rwo 9208.04 15:06 Graven Imagery + ********************************************************************/ diff --git a/libvncauth/vncauth.c b/libvncauth/vncauth.c new file mode 100644 index 0000000..b5d4283 --- /dev/null +++ b/libvncauth/vncauth.c @@ -0,0 +1,161 @@ +/* + * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * vncauth.c - Functions for VNC password management and authentication. + */ + +#include +#include +#include +#include +#include +#include +#include + + +/* + * We use a fixed key to store passwords, since we assume that our local + * file system is secure but nonetheless don't want to store passwords + * as plaintext. + */ + +unsigned char fixedkey[8] = {23,82,107,6,35,78,88,7}; + + +/* + * Encrypt a password and store it in a file. Returns 0 if successful, + * 1 if the file could not be written. + */ + +int +vncEncryptAndStorePasswd(char *passwd, char *fname) +{ + FILE *fp; + int i; + unsigned char encryptedPasswd[8]; + + if ((fp = fopen(fname,"w")) == NULL) return 1; + + chmod(fname, S_IRUSR|S_IWUSR); + + /* pad password with nulls */ + + for (i = 0; i < 8; i++) { + if (i < strlen(passwd)) { + encryptedPasswd[i] = passwd[i]; + } else { + encryptedPasswd[i] = 0; + } + } + + /* Do encryption in-place - this way we overwrite our copy of the plaintext + password */ + + deskey(fixedkey, EN0); + des(encryptedPasswd, encryptedPasswd); + + for (i = 0; i < 8; i++) { + putc(encryptedPasswd[i], fp); + } + + fclose(fp); + return 0; +} + + +/* + * Decrypt a password from a file. Returns a pointer to a newly allocated + * string containing the password or a null pointer if the password could + * not be retrieved for some reason. + */ + +char * +vncDecryptPasswdFromFile(char *fname) +{ + FILE *fp; + int i, ch; + unsigned char *passwd = (unsigned char *)malloc(9); + + if ((fp = fopen(fname,"r")) == NULL) return NULL; + + for (i = 0; i < 8; i++) { + ch = getc(fp); + if (ch == EOF) { + fclose(fp); + return NULL; + } + passwd[i] = ch; + } + + fclose(fp); + + deskey(fixedkey, DE1); + des(passwd, passwd); + + passwd[8] = 0; + + return (char *)passwd; +} + + +/* + * Generate CHALLENGESIZE random bytes for use in challenge-response + * authentication. + */ + +void +vncRandomBytes(unsigned char *bytes) +{ + int i; + unsigned int seed = (unsigned int) time(0); + + srandom(seed); + for (i = 0; i < CHALLENGESIZE; i++) { + bytes[i] = (unsigned char)(random() & 255); + } +} + + +/* + * Encrypt CHALLENGESIZE bytes in memory using a password. + */ + +void +vncEncryptBytes(unsigned char *bytes, char *passwd) +{ + unsigned char key[8]; + int i; + + /* key is simply password padded with nulls */ + + for (i = 0; i < 8; i++) { + if (i < strlen(passwd)) { + key[i] = passwd[i]; + } else { + key[i] = 0; + } + } + + deskey(key, EN0); + + for (i = 0; i < CHALLENGESIZE; i += 8) { + des(bytes+i, bytes+i); + } +} diff --git a/libvncauth/vncauth.h b/libvncauth/vncauth.h new file mode 100644 index 0000000..86dc455 --- /dev/null +++ b/libvncauth/vncauth.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * vncauth.h - describes the functions provided by the vncauth library. + */ + +#define MAXPWLEN 8 +#define CHALLENGESIZE 16 + +extern int vncEncryptAndStorePasswd(char *passwd, char *fname); +extern char *vncDecryptPasswdFromFile(char *fname); +extern void vncRandomBytes(unsigned char *bytes); +extern void vncEncryptBytes(unsigned char *bytes, char *passwd); diff --git a/mac.c b/mac.c new file mode 100644 index 0000000..8376f32 --- /dev/null +++ b/mac.c @@ -0,0 +1,388 @@ + +/* + * OSXvnc Copyright (C) 2001 Dan McGuirk . + * Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge. + * All Rights Reserved. + * + * Cut in two parts by Johannes Schindelin (2001): libvncserver and OSXvnc. + * + * + * This file implements every system specific function for Mac OS X. + * + * It includes the init function: + * + void rfbScreenInit(void) + * + * the function to get the address of the framebuffer: + * + char *rfbGetFramebuffer(void) + * + * keyboard functions: + * + void KbdAddEvent(down, keySym, cl) + Bool down; + KeySym keySym; + rfbClientPtr cl; + void KbdReleaseAllKeys() + * + * the mouse functions: + * + void PtrAddEvent(buttonMask, x, y, cl) + int buttonMask; + int x; + int y; + rfbClientPtr cl; + * + * and the EventLoop: + * + void runEventLoop() + * + * These six functions have to be defined by every VNC server using + * libvncserver. + * + * The main function just calls runVNCServer. This is different + * for more complex users of libvncserver. + * + */ + +#include "rfb.h" +#include +#include +#include + +void +rfbScreenInit(void) +{ + int bitsPerSample; + int samplesPerPixel; + + rfbScreen.width = CGDisplayPixelsWide(kCGDirectMainDisplay); + rfbScreen.height = CGDisplayPixelsHigh(kCGDirectMainDisplay); + rfbScreen.bitsPerPixel = rfbScreen.depth = + CGDisplayBitsPerPixel(kCGDirectMainDisplay); + gethostname(rfbThisHost, 255); + rfbScreen.paddedWidthInBytes = CGDisplayBytesPerRow(kCGDirectMainDisplay); + rfbServerFormat.bitsPerPixel = rfbScreen.bitsPerPixel; + rfbServerFormat.depth = rfbScreen.depth; + rfbServerFormat.bigEndian = !(*(char *)&rfbEndianTest); + rfbServerFormat.trueColour = TRUE; + + bitsPerSample = CGDisplayBitsPerSample(kCGDirectMainDisplay); + samplesPerPixel = CGDisplaySamplesPerPixel(kCGDirectMainDisplay); + if (samplesPerPixel != 3) { + rfbLog("screen format not supported. exiting.\n"); + exit(1); + } + + /* This works for 16 and 32-bit, but not for 8-bit. + What should it be for 8-bit? (Shouldn't 8-bit use a colormap?) */ + rfbServerFormat.redMax = (1 << bitsPerSample) - 1; + rfbServerFormat.greenMax = (1 << bitsPerSample) - 1; + rfbServerFormat.blueMax = (1 << bitsPerSample) - 1; + rfbServerFormat.redShift = bitsPerSample * 2; + rfbServerFormat.greenShift = bitsPerSample; + rfbServerFormat.blueShift = 0; + + /* We want to use the X11 REGION_* macros without having an actual + X11 ScreenPtr, so we do this. Pretty ugly, but at least it lets us + avoid hacking up regionstr.h, or changing every call to REGION_* + (which actually I should probably do eventually). */ + hackScreen.RegionCreate = miRegionCreate; + hackScreen.RegionInit = miRegionInit; + hackScreen.RegionCopy = miRegionCopy; + hackScreen.RegionDestroy = miRegionDestroy; + hackScreen.RegionUninit = miRegionUninit; + hackScreen.Intersect = miIntersect; + hackScreen.Union = miUnion; + hackScreen.Subtract = miSubtract; + hackScreen.Inverse = miInverse; + hackScreen.RegionReset = miRegionReset; + hackScreen.TranslateRegion = miTranslateRegion; + hackScreen.RectIn = miRectIn; + hackScreen.PointInRegion = miPointInRegion; + hackScreen.RegionNotEmpty = miRegionNotEmpty; + hackScreen.RegionEmpty = miRegionEmpty; + hackScreen.RegionExtents = miRegionExtents; + hackScreen.RegionAppend = miRegionAppend; + hackScreen.RegionValidate = miRegionValidate; +} + +char * +rfbGetFramebuffer(void) +{ + return (char *)CGDisplayBaseAddress(kCGDirectMainDisplay); +} + +/* Where do I get the "official" list of Mac key codes? + Ripped these out of a Mac II emulator called Basilisk II + that I found on the net. */ +static int keyTable[] = { + /* The alphabet */ + XK_A, 0, /* A */ + XK_B, 11, /* B */ + XK_C, 8, /* C */ + XK_D, 2, /* D */ + XK_E, 14, /* E */ + XK_F, 3, /* F */ + XK_G, 5, /* G */ + XK_H, 4, /* H */ + XK_I, 34, /* I */ + XK_J, 38, /* J */ + XK_K, 40, /* K */ + XK_L, 37, /* L */ + XK_M, 46, /* M */ + XK_N, 45, /* N */ + XK_O, 31, /* O */ + XK_P, 35, /* P */ + XK_Q, 12, /* Q */ + XK_R, 15, /* R */ + XK_S, 1, /* S */ + XK_T, 17, /* T */ + XK_U, 32, /* U */ + XK_V, 9, /* V */ + XK_W, 13, /* W */ + XK_X, 7, /* X */ + XK_Y, 16, /* Y */ + XK_Z, 6, /* Z */ + XK_a, 0, /* a */ + XK_b, 11, /* b */ + XK_c, 8, /* c */ + XK_d, 2, /* d */ + XK_e, 14, /* e */ + XK_f, 3, /* f */ + XK_g, 5, /* g */ + XK_h, 4, /* h */ + XK_i, 34, /* i */ + XK_j, 38, /* j */ + XK_k, 40, /* k */ + XK_l, 37, /* l */ + XK_m, 46, /* m */ + XK_n, 45, /* n */ + XK_o, 31, /* o */ + XK_p, 35, /* p */ + XK_q, 12, /* q */ + XK_r, 15, /* r */ + XK_s, 1, /* s */ + XK_t, 17, /* t */ + XK_u, 32, /* u */ + XK_v, 9, /* v */ + XK_w, 13, /* w */ + XK_x, 7, /* x */ + XK_y, 16, /* y */ + XK_z, 6, /* z */ + + /* Numbers */ + XK_0, 29, /* 0 */ + XK_1, 18, /* 1 */ + XK_2, 19, /* 2 */ + XK_3, 20, /* 3 */ + XK_4, 21, /* 4 */ + XK_5, 23, /* 5 */ + XK_6, 22, /* 6 */ + XK_7, 26, /* 7 */ + XK_8, 28, /* 8 */ + XK_9, 25, /* 9 */ + + /* Symbols */ + XK_exclam, 18, /* ! */ + XK_at, 19, /* @ */ + XK_numbersign, 20, /* # */ + XK_dollar, 21, /* $ */ + XK_percent, 23, /* % */ + XK_asciicircum, 22, /* ^ */ + XK_ampersand, 26, /* & */ + XK_asterisk, 28, /* * */ + XK_parenleft, 25, /* ( */ + XK_parenright, 29, /* ) */ + XK_minus, 27, /* - */ + XK_underscore, 27, /* _ */ + XK_equal, 24, /* = */ + XK_plus, 24, /* + */ + XK_grave, 10, /* ` */ /* XXX ? */ + XK_asciitilde, 10, /* ~ */ + XK_bracketleft, 33, /* [ */ + XK_braceleft, 33, /* { */ + XK_bracketright, 30, /* ] */ + XK_braceright, 30, /* } */ + XK_semicolon, 41, /* ; */ + XK_colon, 41, /* : */ + XK_apostrophe, 39, /* ' */ + XK_quotedbl, 39, /* " */ + XK_comma, 43, /* , */ + XK_less, 43, /* < */ + XK_period, 47, /* . */ + XK_greater, 47, /* > */ + XK_slash, 44, /* / */ + XK_question, 44, /* ? */ + XK_backslash, 42, /* \ */ + XK_bar, 42, /* | */ + + /* "Special" keys */ + XK_space, 49, /* Space */ + XK_Return, 36, /* Return */ + XK_Delete, 117, /* Delete */ + XK_Tab, 48, /* Tab */ + XK_Escape, 53, /* Esc */ + XK_Caps_Lock, 57, /* Caps Lock */ + XK_Num_Lock, 71, /* Num Lock */ + XK_Scroll_Lock, 107, /* Scroll Lock */ + XK_Pause, 113, /* Pause */ + XK_BackSpace, 51, /* Backspace */ + XK_Insert, 114, /* Insert */ + + /* Cursor movement */ + XK_Up, 126, /* Cursor Up */ + XK_Down, 125, /* Cursor Down */ + XK_Left, 123, /* Cursor Left */ + XK_Right, 124, /* Cursor Right */ + XK_Page_Up, 116, /* Page Up */ + XK_Page_Down, 121, /* Page Down */ + XK_Home, 115, /* Home */ + XK_End, 119, /* End */ + + /* Numeric keypad */ + XK_KP_0, 82, /* KP 0 */ + XK_KP_1, 83, /* KP 1 */ + XK_KP_2, 84, /* KP 2 */ + XK_KP_3, 85, /* KP 3 */ + XK_KP_4, 86, /* KP 4 */ + XK_KP_5, 87, /* KP 5 */ + XK_KP_6, 88, /* KP 6 */ + XK_KP_7, 89, /* KP 7 */ + XK_KP_8, 91, /* KP 8 */ + XK_KP_9, 92, /* KP 9 */ + XK_KP_Enter, 76, /* KP Enter */ + XK_KP_Decimal, 65, /* KP . */ + XK_KP_Add, 69, /* KP + */ + XK_KP_Subtract, 78, /* KP - */ + XK_KP_Multiply, 67, /* KP * */ + XK_KP_Divide, 75, /* KP / */ + + /* Function keys */ + XK_F1, 122, /* F1 */ + XK_F2, 120, /* F2 */ + XK_F3, 99, /* F3 */ + XK_F4, 118, /* F4 */ + XK_F5, 96, /* F5 */ + XK_F6, 97, /* F6 */ + XK_F7, 98, /* F7 */ + XK_F8, 100, /* F8 */ + XK_F9, 101, /* F9 */ + XK_F10, 109, /* F10 */ + XK_F11, 103, /* F11 */ + XK_F12, 111, /* F12 */ + + /* Modifier keys */ + XK_Shift_L, 56, /* Shift Left */ + XK_Shift_R, 56, /* Shift Right */ + XK_Control_L, 59, /* Ctrl Left */ + XK_Control_R, 59, /* Ctrl Right */ + XK_Meta_L, 58, /* Logo Left (-> Option) */ + XK_Meta_R, 58, /* Logo Right (-> Option) */ + XK_Alt_L, 55, /* Alt Left (-> Command) */ + XK_Alt_R, 55, /* Alt Right (-> Command) */ + + /* Weirdness I can't figure out */ + /* XK_3270_PrintScreen, 105, /* PrintScrn */ /* XXX ? */ + /* ??? 94, 50, /* International */ + XK_Menu, 50, /* Menu (-> International) */ +}; + +void +KbdAddEvent(down, keySym, cl) + Bool down; + KeySym keySym; + rfbClientPtr cl; +{ + int i; + CGKeyCode keyCode = -1; + int found = 0; + + for (i = 0; i < (sizeof(keyTable) / sizeof(int)); i += 2) { + if (keyTable[i] == keySym) { + keyCode = keyTable[i+1]; + found = 1; + break; + } + } + + if (!found) { + rfbLog("warning: couldn't figure out keycode for X keysym %d (0x%x)\n", + (int)keySym, (int)keySym); + } else { + /* Hopefully I can get away with not specifying a CGCharCode. + (Why would you need both?) */ + CGPostKeyboardEvent((CGCharCode)0, keyCode, down); + } +} + +void +PtrAddEvent(buttonMask, x, y, cl) + int buttonMask; + int x; + int y; + rfbClientPtr cl; +{ + CGPoint position; + + position.x = x; + position.y = y; + + CGPostMouseEvent(position, TRUE, 8, + (buttonMask & (1 << 0)) ? TRUE : FALSE, + (buttonMask & (1 << 1)) ? TRUE : FALSE, + (buttonMask & (1 << 2)) ? TRUE : FALSE, + (buttonMask & (1 << 3)) ? TRUE : FALSE, + (buttonMask & (1 << 4)) ? TRUE : FALSE, + (buttonMask & (1 << 5)) ? TRUE : FALSE, + (buttonMask & (1 << 6)) ? TRUE : FALSE, + (buttonMask & (1 << 7)) ? TRUE : FALSE); +} + +void +KbdReleaseAllKeys() +{ + /* Doesn't seem to be possible. */ +} + +static void +refreshCallback(CGRectCount count, const CGRect *rectArray, void *ignore) +{ + BoxRec box; + RegionRec region; + rfbClientIteratorPtr iterator; + rfbClientPtr cl; + int i; + + for (i = 0; i < count; i++) { + box.x1 = rectArray[i].origin.x; + box.y1 = rectArray[i].origin.y; + box.x2 = box.x1 + rectArray[i].size.width; + box.y2 = box.y1 + rectArray[i].size.height; + + SAFE_REGION_INIT(&hackScreen, ®ion, &box, 0); + + iterator = rfbGetClientIterator(); + while ((cl = rfbClientIteratorNext(iterator)) != NULL) { + pthread_mutex_lock(&cl->updateMutex); + REGION_UNION(&hackScreen,&cl->modifiedRegion,&cl->modifiedRegion,®ion); + pthread_cond_signal(&cl->updateCond); + pthread_mutex_unlock(&cl->updateMutex); + } + rfbReleaseClientIterator(iterator); + + REGION_UNINIT(&hackScreen, ®ion); + } +} + +void runEventLoop() +{ + CGRegisterScreenRefreshCallback(refreshCallback, NULL); + + RunApplicationEventLoop(); +} + +int main(int argc,char *argv[]) +{ + runVNCServer(argc,argv); +} diff --git a/main.c b/main.c new file mode 100644 index 0000000..347784a --- /dev/null +++ b/main.c @@ -0,0 +1,426 @@ +/* + * OSXvnc Copyright (C) 2001 Dan McGuirk . + * Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge. + * All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include +#include +#include +#include + +#ifndef false +#define false 0 +#define true -1 +#endif + +#include +#include +#include +#ifdef HAVE_PTHREADS +#include +#endif +#include +#include + +#include "rfb.h" + +#ifdef HAVE_PTHREADS +pthread_mutex_t logMutex; +#endif + +/* + * rfbLog prints a time-stamped message to the log file (stderr). + */ + +void +rfbLog(char *format, ...) +{ + va_list args; + char buf[256]; + time_t clock; + + IF_PTHREADS(pthread_mutex_lock(&logMutex)); + va_start(args, format); + + time(&clock); + strftime(buf, 255, "%d/%m/%Y %T ", localtime(&clock)); + fprintf(stderr, buf); + + vfprintf(stderr, format, args); + fflush(stderr); + + va_end(args); + IF_PTHREADS(pthread_mutex_unlock(&logMutex)); +} + +void rfbLogPerror(char *str) +{ + rfbLog("%s: %s\n", str, strerror(errno)); +} + + +void rfbMarkRegionAsModified(rfbScreenInfoPtr rfbScreen,RegionPtr modRegion) +{ + rfbClientIteratorPtr iterator; + rfbClientPtr cl; + iterator=rfbGetClientIterator(rfbScreen); + while((cl=rfbClientIteratorNext(iterator))) { + REGION_UNION(cl->screen,&cl->modifiedRegion,&cl->modifiedRegion,modRegion); + } + + rfbReleaseClientIterator(iterator); +} + +void rfbMarkRectAsModified(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2) +{ + BoxRec box; + RegionRec region; + box.x1=x1; box.y1=y1; box.x2=x2; box.y2=y2; + REGION_INIT(cl->screen,®ion,&box,0); + rfbMarkRegionAsModified(rfbScreen,®ion); +} + +int rfbDeferUpdateTime = 40; /* ms */ + +#ifdef HAVE_PTHREADS +static void * +clientOutput(void *data) +{ + rfbClientPtr cl = (rfbClientPtr)data; + Bool haveUpdate; + RegionRec updateRegion; + + while (1) { + haveUpdate = false; + pthread_mutex_lock(&cl->updateMutex); + while (!haveUpdate) { + if (cl->sock == -1) { + /* Client has disconnected. */ + pthread_mutex_unlock(&cl->updateMutex); + return NULL; + } + + REGION_INIT(&hackScreen, &updateRegion, NullBox, 0); + REGION_INTERSECT(&hackScreen, &updateRegion, + &cl->modifiedRegion, &cl->requestedRegion); + haveUpdate = REGION_NOTEMPTY(&hackScreen, &updateRegion); + REGION_UNINIT(&hackScreen, &updateRegion); + + if (!haveUpdate) { + pthread_cond_wait(&cl->updateCond, &cl->updateMutex); + } + } + + /* OK, now, to save bandwidth, wait a little while for more + updates to come along. */ + pthread_mutex_unlock(&cl->updateMutex); + usleep(rfbDeferUpdateTime * 1000); + + /* Now, get the region we're going to update, and remove + it from cl->modifiedRegion _before_ we send the update. + That way, if anything that overlaps the region we're sending + is updated, we'll be sure to do another update later. */ + pthread_mutex_lock(&cl->updateMutex); + REGION_INIT(&hackScreen, &updateRegion, NullBox, 0); + REGION_INTERSECT(&hackScreen, &updateRegion, + &cl->modifiedRegion, &cl->requestedRegion); + REGION_SUBTRACT(&hackScreen, &cl->modifiedRegion, + &cl->modifiedRegion, &updateRegion); + pthread_mutex_unlock(&cl->updateMutex); + + /* Now actually send the update. */ + rfbSendFramebufferUpdate(cl, updateRegion); + + REGION_UNINIT(&hackScreen, &updateRegion); + } + + return NULL; +} + +static void * +clientInput(void *data) +{ + rfbClientPtr cl = (rfbClientPtr)data; + pthread_t output_thread; + pthread_create(&output_thread, NULL, clientOutput, (void *)cl); + + while (1) { + rfbProcessClientMessage(cl); + if (cl->sock == -1) { + /* Client has disconnected. */ + break; + } + } + + /* Get rid of the output thread. */ + pthread_mutex_lock(&cl->updateMutex); + pthread_cond_signal(&cl->updateCond); + pthread_mutex_unlock(&cl->updateMutex); + pthread_join(output_thread, NULL); + + rfbClientConnectionGone(cl); + + return NULL; +} + +void* +listenerRun(void *data) +{ + rfbScreenInfoPtr rfbScreen=(rfbScreenInfoPtr)data; + int listen_fd, client_fd; + struct sockaddr_in sin, peer; + pthread_t client_thread; + rfbClientPtr cl; + int len, value; + + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = INADDR_ANY; + sin.sin_port = htons(rfbScreen->rfbPort ? rfbScreen->rfbPort : 5901); + + if ((listen_fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { + return NULL; + } + value = 1; + if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, + &value, sizeof(value)) < 0) { + rfbLog("setsockopt SO_REUSEADDR failed\n"); + } + + if (bind(listen_fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) { + rfbLog("failed to bind socket\n"); + exit(1); + } + + if (listen(listen_fd, 5) < 0) { + rfbLog("listen failed\n"); + exit(1); + } + + len = sizeof(peer); + while ((client_fd = accept(listen_fd, + (struct sockaddr *)&peer, &len)) >= 0) { + cl = rfbNewClient(rfbScreen,client_fd); + + pthread_create(&client_thread, NULL, clientInput, (void *)cl); + len = sizeof(peer); + } + + rfbLog("accept failed\n"); + exit(1); +} +#endif + +static void +usage(void) +{ + fprintf(stderr, "-rfbport port TCP port for RFB protocol\n"); + fprintf(stderr, "-rfbwait time max time in ms to wait for RFB client\n"); + fprintf(stderr, "-rfbauth passwd-file use authentication on RFB protocol\n" + " (use 'storepasswd' to create a password file)\n"); + fprintf(stderr, "-deferupdate time time in ms to defer updates " + "(default 40)\n"); + fprintf(stderr, "-desktop name VNC desktop name (default \"LibVNCServer\")\n"); + fprintf(stderr, "-alwaysshared always treat new clients as shared\n"); + fprintf(stderr, "-nevershared never treat new clients as shared\n"); + fprintf(stderr, "-dontdisconnect don't disconnect existing clients when a " + "new non-shared\n" + " connection comes in (refuse new connection " + "instead)\n"); + exit(1); +} + +static void +processArguments(rfbScreenInfoPtr rfbScreen,int argc, char *argv[]) +{ + int i; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-rfbport") == 0) { /* -rfbport port */ + if (i + 1 >= argc) usage(); + rfbScreen->rfbPort = atoi(argv[++i]); + } else if (strcmp(argv[i], "-rfbwait") == 0) { /* -rfbwait ms */ + if (i + 1 >= argc) usage(); + rfbScreen->rfbMaxClientWait = atoi(argv[++i]); + } else if (strcmp(argv[i], "-rfbauth") == 0) { /* -rfbauth passwd-file */ + if (i + 1 >= argc) usage(); + rfbScreen->rfbAuthPasswdFile = argv[++i]; + } else if (strcmp(argv[i], "-deferupdate") == 0) { /* -deferupdate ms */ + if (i + 1 >= argc) usage(); + rfbScreen->rfbDeferUpdateTime = atoi(argv[++i]); + } else if (strcmp(argv[i], "-desktop") == 0) { /* -desktop desktop-name */ + if (i + 1 >= argc) usage(); + rfbScreen->desktopName = argv[++i]; + } else if (strcmp(argv[i], "-alwaysshared") == 0) { + rfbScreen->rfbAlwaysShared = TRUE; + } else if (strcmp(argv[i], "-nevershared") == 0) { + rfbScreen->rfbNeverShared = TRUE; + } else if (strcmp(argv[i], "-dontdisconnect") == 0) { + rfbScreen->rfbDontDisconnect = TRUE; + } else { + usage(); + } + } +} + +void +DefaultKbdAddEvent(down, keySym, cl) + Bool down; + KeySym keySym; + rfbClientPtr cl; +{ +} + +void +DefaultPtrAddEvent(buttonMask, x, y, cl) + int buttonMask; + int x; + int y; + rfbClientPtr cl; +{ +} + +void +DefaultKbdReleaseAllKeys(cl) + rfbClientPtr cl; +{ +} + +void DefaultSetXCutText(text,len,cl) + char* text; + int len; + rfbClientPtr cl; +{ +} + +rfbScreenInfoPtr rfbDefaultScreenInit(int argc,char** argv) +{ + int bitsPerSample,samplesPerPixel; + + rfbScreenInfoPtr rfbScreen=malloc(sizeof(rfbScreenInfo)); + rfbScreen->rfbPort=5900; + rfbScreen->socketInitDone=FALSE; + rfbScreen->inetdSock=-1; + rfbScreen->udpSock=-1; + rfbScreen->udpSockConnected=FALSE; + rfbScreen->maxFd=0; + rfbScreen->rfbListenSock=-1; + rfbScreen->udpPort=0; + rfbScreen->inetdInitDone = FALSE; + rfbScreen->desktopName = "LibVNCServer"; + rfbScreen->rfbAlwaysShared = FALSE; + rfbScreen->rfbNeverShared = FALSE; + rfbScreen->rfbDontDisconnect = FALSE; + + processArguments(rfbScreen,argc,argv); + + rfbScreen->width = 640; + rfbScreen->height = 480; + rfbScreen->bitsPerPixel = rfbScreen->depth = 32; + gethostname(rfbScreen->rfbThisHost, 255); + rfbScreen->paddedWidthInBytes = 640*4; + rfbScreen->rfbServerFormat.bitsPerPixel = rfbScreen->bitsPerPixel; + rfbScreen->rfbServerFormat.depth = rfbScreen->depth; + rfbScreen->rfbServerFormat.bigEndian = !(*(char *)&rfbEndianTest); + rfbScreen->rfbServerFormat.trueColour = TRUE; + + bitsPerSample = 8; + samplesPerPixel = 3; + if (samplesPerPixel != 3) { + rfbLog("screen format not supported. exiting.\n"); + exit(1); + } + + /* This works for 16 and 32-bit, but not for 8-bit. + What should it be for 8-bit? (Shouldn't 8-bit use a colormap?) */ + rfbScreen->rfbServerFormat.redMax = (1 << bitsPerSample) - 1; + rfbScreen->rfbServerFormat.greenMax = (1 << bitsPerSample) - 1; + rfbScreen->rfbServerFormat.blueMax = (1 << bitsPerSample) - 1; + rfbScreen->rfbServerFormat.redShift = bitsPerSample * 2; + rfbScreen->rfbServerFormat.greenShift = bitsPerSample; + rfbScreen->rfbServerFormat.blueShift = 0; + + /* We want to use the X11 REGION_* macros without having an actual + X11 ScreenPtr, so we do this. Pretty ugly, but at least it lets us + avoid hacking up regionstr.h, or changing every call to REGION_* + (which actually I should probably do eventually). */ + rfbScreen->screen.RegionCreate = miRegionCreate; + rfbScreen->screen.RegionInit = miRegionInit; + rfbScreen->screen.RegionCopy = miRegionCopy; + rfbScreen->screen.RegionDestroy = miRegionDestroy; + rfbScreen->screen.RegionUninit = miRegionUninit; + rfbScreen->screen.Intersect = miIntersect; + rfbScreen->screen.Union = miUnion; + rfbScreen->screen.Subtract = miSubtract; + rfbScreen->screen.Inverse = miInverse; + rfbScreen->screen.RegionReset = miRegionReset; + rfbScreen->screen.TranslateRegion = miTranslateRegion; + rfbScreen->screen.RectIn = miRectIn; + rfbScreen->screen.PointInRegion = miPointInRegion; + rfbScreen->screen.RegionNotEmpty = miRegionNotEmpty; + rfbScreen->screen.RegionEmpty = miRegionEmpty; + rfbScreen->screen.RegionExtents = miRegionExtents; + rfbScreen->screen.RegionAppend = miRegionAppend; + rfbScreen->screen.RegionValidate = miRegionValidate; + + rfbScreen->kbdAddEvent = DefaultKbdAddEvent; + rfbScreen->kbdReleaseAllKeys = DefaultKbdReleaseAllKeys; + rfbScreen->ptrAddEvent = DefaultPtrAddEvent; + rfbScreen->setXCutText = DefaultSetXCutText; + return(rfbScreen); +} + +void +processEvents(rfbScreenInfoPtr rfbScreen,long usec) +{ + rfbCheckFds(rfbScreen,usec); + //httpCheckFds(rfbScreen); +#ifdef CORBA + corbaCheckFds(rfbScreen); +#endif + { + rfbClientIteratorPtr iterator; + rfbClientPtr cl; + iterator=rfbGetClientIterator(rfbScreen); + while((cl=rfbClientIteratorNext(iterator))) + if(cl->sock>=0 && FB_UPDATE_PENDING(cl)) { + rfbSendFramebufferUpdate(cl,cl->modifiedRegion); + } + rfbReleaseClientIterator(iterator); + } +} + +void runEventLoop(rfbScreenInfoPtr rfbScreen, long usec, Bool runInBackground) +{ + if(runInBackground) { +#ifdef HAVE_PTHREADS + pthread_t listener_thread; + + rfbClientListInit(rfbScreen); + //pthread_mutex_init(&logMutex, NULL); + pthread_create(&listener_thread, NULL, listenerRun, rfbScreen); + return; +#else + fprintf(stderr,"Can't run in background, because I don't have PThreads!\n"); +#endif + } + + rfbInitSockets(rfbScreen); + while(1) + processEvents(rfbScreen,usec); +} diff --git a/miregion.c b/miregion.c new file mode 100644 index 0000000..37f4927 --- /dev/null +++ b/miregion.c @@ -0,0 +1,2421 @@ +/*********************************************************** + +Copyright (c) 1987, 1988, 1989 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. + + +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. + +******************************************************************/ +/* $XConsortium: miregion.c,v 1.60 94/04/17 20:27:49 dpw Exp $ */ + +#include +#include +#include "miscstruct.h" +#include "regionstr.h" +#include "Xprotostr.h" +#include "gc.h" + +#if defined (__GNUC__) && !defined (NO_INLINES) +#define INLINE __inline +#else +#define INLINE +#endif + +/* + * hack until callers of these functions can deal with out-of-memory + */ + +extern Bool Must_have_memory; + +#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(miValidRegion(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 miRegionValidate 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 xallocData(n) (RegDataPtr)xalloc(REGION_SZOF(n)) +#define xfreeData(reg) if ((reg)->data && (reg)->data->size) xfree((reg)->data) + +#define RECTALLOC(pReg,n) \ +if (!(pReg)->data || (((pReg)->data->numRects + (n)) > (pReg)->data->size)) \ + miRectAlloc(pReg, n) + +#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))\ + { \ + miRectAlloc(pReg, 1); \ + pNextRect = REGION_TOP(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)) \ +{ \ + RegDataPtr NewData; \ + NewData = (RegDataPtr)xrealloc((reg)->data, REGION_SZOF(numRects)); \ + if (NewData) \ + { \ + NewData->size = (numRects); \ + (reg)->data = NewData; \ + } \ +} + + +BoxRec miEmptyBox = {0, 0, 0, 0}; +RegDataRec miEmptyData = {0, 0}; + +#ifdef DEBUG +int +miPrintRegion(rgn) + RegionPtr rgn; +{ + int num, size; + register int i; + BoxPtr rects; + + num = REGION_NUM_RECTS(rgn); + size = REGION_SIZE(rgn); + rects = REGION_RECTS(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); +} + + +Bool +miRegionsEqual(reg1, reg2) + RegionPtr reg1; + RegionPtr reg2; +{ + int i; + BoxPtr rects1, rects2; + + if (reg1->extents.x1 != reg2->extents.x1) return FALSE; + if (reg1->extents.x2 != reg2->extents.x2) return FALSE; + if (reg1->extents.y1 != reg2->extents.y1) return FALSE; + if (reg1->extents.y2 != reg2->extents.y2) return FALSE; + if (REGION_NUM_RECTS(reg1) != REGION_NUM_RECTS(reg2)) return FALSE; + + rects1 = REGION_RECTS(reg1); + rects2 = REGION_RECTS(reg2); + for (i = 0; i != REGION_NUM_RECTS(reg1); i++) { + if (rects1[i].x1 != rects2[i].x1) return FALSE; + if (rects1[i].x2 != rects2[i].x2) return FALSE; + if (rects1[i].y1 != rects2[i].y1) return FALSE; + if (rects1[i].y2 != rects2[i].y2) return FALSE; + } + return TRUE; +} + +Bool +miValidRegion(reg) + RegionPtr reg; +{ + register int i, numRects; + + if ((reg->extents.x1 > reg->extents.x2) || + (reg->extents.y1 > reg->extents.y2)) + return FALSE; + numRects = REGION_NUM_RECTS(reg); + if (!numRects) + return ((reg->extents.x1 == reg->extents.x2) && + (reg->extents.y1 == reg->extents.y2) && + (reg->data->size || (reg->data == &miEmptyData))); + else if (numRects == 1) + return (!reg->data); + else + { + register BoxPtr pboxP, pboxN; + BoxRec box; + + pboxP = REGION_RECTS(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 +miRegionCreate(rect, size) + BoxPtr rect; + int size; +{ + register RegionPtr pReg; + + Must_have_memory = TRUE; /* XXX */ + pReg = (RegionPtr)xalloc(sizeof(RegionRec)); + Must_have_memory = FALSE; /* XXX */ + if (rect) + { + pReg->extents = *rect; + pReg->data = (RegDataPtr)NULL; + } + else + { + pReg->extents = miEmptyBox; + if ((size > 1) && (pReg->data = xallocData(size))) + { + pReg->data->size = size; + pReg->data->numRects = 0; + } + else + pReg->data = &miEmptyData; + } + return(pReg); +} + +/***************************************************************** + * RegionInit(pReg, rect, size) + * Outer region rect is statically allocated. + *****************************************************************/ + +void +miRegionInit(pReg, rect, size) + RegionPtr pReg; + BoxPtr rect; + int size; +{ + if (rect) + { + pReg->extents = *rect; + pReg->data = (RegDataPtr)NULL; + } + else + { + pReg->extents = miEmptyBox; + if ((size > 1) && (pReg->data = xallocData(size))) + { + pReg->data->size = size; + pReg->data->numRects = 0; + } + else + pReg->data = &miEmptyData; + } +} + +void +miRegionDestroy(pReg) + RegionPtr pReg; +{ + good(pReg); + xfreeData(pReg); + xfree(pReg); +} + +void +miRegionUninit(pReg) + RegionPtr pReg; +{ + good(pReg); + xfreeData(pReg); +} + +Bool +miRectAlloc(pRgn, n) + register RegionPtr pRgn; + int n; +{ + Must_have_memory = TRUE; /* XXX */ + if (!pRgn->data) + { + n++; + pRgn->data = xallocData(n); + pRgn->data->numRects = 1; + *REGION_BOXPTR(pRgn) = pRgn->extents; + } + else if (!pRgn->data->size) + { + pRgn->data = xallocData(n); + 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; + pRgn->data = (RegDataPtr)xrealloc(pRgn->data, REGION_SZOF(n)); + } + Must_have_memory = FALSE; /* XXX */ + pRgn->data->size = n; + return TRUE; +} + +Bool +miRegionCopy(dst, src) + register RegionPtr dst; + register RegionPtr src; +{ + good(dst); + good(src); + if (dst == src) + return TRUE; + dst->extents = src->extents; + if (!src->data || !src->data->size) + { + xfreeData(dst); + dst->data = src->data; + return TRUE; + } + if (!dst->data || (dst->data->size < src->data->numRects)) + { + xfreeData(dst); + Must_have_memory = TRUE; /* XXX */ + dst->data = xallocData(src->data->numRects); + Must_have_memory = FALSE; /* XXX */ + dst->data->size = src->data->numRects; + } + dst->data->numRects = src->data->numRects; + memmove((char *)REGION_BOXPTR(dst),(char *)REGION_BOXPTR(src), + dst->data->numRects * sizeof(BoxRec)); + return TRUE; +} + + +/*====================================================================== + * Generic Region Operator + *====================================================================*/ + +/*- + *----------------------------------------------------------------------- + * miCoalesce -- + * 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 miRegionOp. + * + * 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 +miCoalesce (pReg, prevStart, curStart) + 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 = REGION_BOX(pReg, prevStart); + pCurBox = REGION_BOX(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 miCoalesce */ + +#define Coalesce(newReg, prevBand, curBand) \ + if (curBand - prevBand == newReg->data->numRects - curBand) { \ + prevBand = miCoalesce(newReg, prevBand, curBand); \ + } else { \ + prevBand = curBand; \ + } + +/*- + *----------------------------------------------------------------------- + * miAppendNonO -- + * 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 +miAppendNonO (pReg, r, rEnd, y1, y2) + 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 = REGION_TOP(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 *)REGION_TOP(newReg),(char *)r, \ + newRects * sizeof(BoxRec)); \ + newReg->data->numRects += newRects; \ + } \ +} + +/*- + *----------------------------------------------------------------------- + * miRegionOp -- + * Apply an operation to two regions. Called by miUnion, miInverse, + * miSubtract, miIntersect.... 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. + * + *----------------------------------------------------------------------- + */ +static Bool +miRegionOp(newReg, reg1, reg2, overlapFunc, appendNon1, appendNon2, pOverlap) + RegionPtr newReg; /* Place to store result */ + RegionPtr reg1; /* First region in operation */ + RegionPtr reg2; /* 2d region in operation */ + Bool (*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; + + /* + * 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 = REGION_RECTS(reg1); + newSize = REGION_NUM_RECTS(reg1); + r1End = r1 + newSize; + numRects = REGION_NUM_RECTS(reg2); + r2 = REGION_RECTS(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 = &miEmptyData; + } + /* guess at new size */ + if (numRects > newSize) + newSize = numRects; + newSize <<= 1; + if (!newReg->data) + newReg->data = &miEmptyData; + else if (newReg->data->size) + newReg->data->numRects = 0; + if (newSize > newReg->data->size) + miRectAlloc(newReg, newSize); + + /* + * 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. miCoalesce, 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; + miAppendNonO(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; + miAppendNonO(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; + miAppendNonO(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; + miAppendNonO(newReg, r2, r2BandEnd, max(r2y1, ybot), r2->y2); + Coalesce(newReg, prevBand, curBand); + /* Append rest of boxes */ + AppendRegions(newReg, r2BandEnd, r2End); + } + + if (oldData) + xfree(oldData); + + if (!(numRects = newReg->data->numRects)) + { + xfreeData(newReg); + newReg->data = &miEmptyData; + } + else if (numRects == 1) + { + newReg->extents = *REGION_BOXPTR(newReg); + xfreeData(newReg); + newReg->data = (RegDataPtr)NULL; + } + else + { + DOWNSIZE(newReg, numRects); + } + + return TRUE; +} + +/*- + *----------------------------------------------------------------------- + * miSetExtents -- + * Reset the extents of a region to what they should be. Called by + * miSubtract and miIntersect as they can't figure it out along the + * way or do so easily, as miUnion can. + * + * Results: + * None. + * + * Side Effects: + * The region's 'extents' structure is overwritten. + * + *----------------------------------------------------------------------- + */ +void +miSetExtents (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 = REGION_BOXPTR(pReg); + pBoxEnd = REGION_END(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); +} + +/*====================================================================== + * Region Intersection + *====================================================================*/ +/*- + *----------------------------------------------------------------------- + * miIntersectO -- + * Handle an overlapping band for miIntersect. + * + * Results: + * TRUE if successful. + * + * Side Effects: + * Rectangles may be added to the region. + * + *----------------------------------------------------------------------- + */ +/*ARGSUSED*/ +static Bool +miIntersectO (pReg, r1, r1End, r2, r2End, y1, y2, pOverlap) + register RegionPtr pReg; + register BoxPtr r1; + BoxPtr r1End; + register BoxPtr r2; + BoxPtr r2End; + short y1; + short y2; + Bool *pOverlap; +{ + register int x1; + register int x2; + register BoxPtr pNextRect; + + pNextRect = REGION_TOP(pReg); + + assert(y1 < y2); + assert(r1 != r1End && r2 != r2End); + + do { + x1 = max(r1->x1, r2->x1); + x2 = min(r1->x2, r2->x2); + + /* + * If there's any overlap between the two rectangles, add that + * overlap to the new region. + */ + if (x1 < x2) + NEWRECT(pReg, pNextRect, x1, y1, x2, y2); + + /* + * Advance the pointer(s) with the leftmost right side, since the next + * rectangle on that list may still overlap the other region's + * current rectangle. + */ + if (r1->x2 == x2) { + r1++; + } + if (r2->x2 == x2) { + r2++; + } + } while ((r1 != r1End) && (r2 != r2End)); + + return TRUE; +} + + +Bool +miIntersect(newReg, reg1, reg2) + register RegionPtr newReg; /* destination Region */ + register RegionPtr reg1; + register RegionPtr reg2; /* source regions */ +{ + good(reg1); + good(reg2); + good(newReg); + /* check for trivial reject */ + if (REGION_NIL(reg1) || REGION_NIL(reg2) || + !EXTENTCHECK(®1->extents, ®2->extents)) + { + /* Covers about 20% of all cases */ + xfreeData(newReg); + newReg->extents.x2 = newReg->extents.x1; + newReg->extents.y2 = newReg->extents.y1; + newReg->data = &miEmptyData; + } + else if (!reg1->data && !reg2->data) + { + /* Covers about 80% of cases that aren't trivially rejected */ + newReg->extents.x1 = max(reg1->extents.x1, reg2->extents.x1); + newReg->extents.y1 = max(reg1->extents.y1, reg2->extents.y1); + newReg->extents.x2 = min(reg1->extents.x2, reg2->extents.x2); + newReg->extents.y2 = min(reg1->extents.y2, reg2->extents.y2); + xfreeData(newReg); + newReg->data = (RegDataPtr)NULL; + } + else if (!reg2->data && SUBSUMES(®2->extents, ®1->extents)) + { + return miRegionCopy(newReg, reg1); + } + else if (!reg1->data && SUBSUMES(®1->extents, ®2->extents)) + { + return miRegionCopy(newReg, reg2); + } + else if (reg1 == reg2) + { + return miRegionCopy(newReg, reg1); + } + else + { + /* General purpose intersection */ + Bool overlap; /* result ignored */ + if (!miRegionOp(newReg, reg1, reg2, miIntersectO, FALSE, FALSE, + &overlap)) + return FALSE; + miSetExtents(newReg); + } + + good(newReg); + return(TRUE); +} + +#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 + *====================================================================*/ + +/*- + *----------------------------------------------------------------------- + * miUnionO -- + * 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 +miUnionO (pReg, r1, r1End, r2, r2End, y1, y2, pOverlap) + 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 = REGION_TOP(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; +} + +Bool +miUnion(newReg, reg1, reg2) + RegionPtr newReg; /* destination Region */ + register RegionPtr reg1; + register RegionPtr reg2; /* source regions */ +{ + Bool overlap; /* result ignored */ + + /* Return TRUE if some overlap between reg1, reg2 */ + good(reg1); + good(reg2); + good(newReg); + /* checks all the simple cases */ + + /* + * Region 1 and 2 are the same + */ + if (reg1 == reg2) + { + return miRegionCopy(newReg, reg1); + } + + /* + * Region 1 is empty + */ + if (REGION_NIL(reg1)) + { + if (newReg != reg2) + return miRegionCopy(newReg, reg2); + return TRUE; + } + + /* + * Region 2 is empty + */ + if (REGION_NIL(reg2)) + { + if (newReg != reg1) + return miRegionCopy(newReg, reg1); + return TRUE; + } + + /* + * Region 1 completely subsumes region 2 + */ + if (!reg1->data && SUBSUMES(®1->extents, ®2->extents)) + { + if (newReg != reg1) + return miRegionCopy(newReg, reg1); + return TRUE; + } + + /* + * Region 2 completely subsumes region 1 + */ + if (!reg2->data && SUBSUMES(®2->extents, ®1->extents)) + { + if (newReg != reg2) + return miRegionCopy(newReg, reg2); + return TRUE; + } + + if (!miRegionOp(newReg, reg1, reg2, miUnionO, TRUE, TRUE, &overlap)) + return FALSE; + + newReg->extents.x1 = min(reg1->extents.x1, reg2->extents.x1); + newReg->extents.y1 = min(reg1->extents.y1, reg2->extents.y1); + newReg->extents.x2 = max(reg1->extents.x2, reg2->extents.x2); + newReg->extents.y2 = max(reg1->extents.y2, reg2->extents.y2); + good(newReg); + return TRUE; +} + + +/*====================================================================== + * Batch Rectangle Union + *====================================================================*/ + +/*- + *----------------------------------------------------------------------- + * miRegionAppend -- + * + * "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 miRegionValidate to ensure that a valid region is constructed. + * + * Results: + * TRUE if successful. + * + * Side Effects: + * dstrgn is modified if rgn has rectangles. + * + */ +Bool +miRegionAppend(dstrgn, rgn) + register RegionPtr dstrgn; + register RegionPtr rgn; +{ + int numRects, dnumRects, size; + BoxPtr new, old; + Bool prepend; + + if (!rgn->data && (dstrgn->data == &miEmptyData)) + { + dstrgn->extents = rgn->extents; + dstrgn->data = (RegDataPtr)NULL; + return TRUE; + } + + numRects = REGION_NUM_RECTS(rgn); + if (!numRects) + return TRUE; + prepend = FALSE; + size = numRects; + dnumRects = REGION_NUM_RECTS(dstrgn); + if (!dnumRects && (size < 200)) + size = 200; /* XXX pick numbers out of a hat */ + RECTALLOC(dstrgn, size); + old = REGION_RECTS(rgn); + if (!dnumRects) + dstrgn->extents = rgn->extents; + else if (dstrgn->extents.x2 > dstrgn->extents.x1) + { + register BoxPtr first, last; + + first = old; + last = REGION_BOXPTR(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 = REGION_BOXPTR(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 = REGION_BOX(dstrgn, numRects); + if (dnumRects == 1) + *new = *REGION_BOXPTR(dstrgn); + else + memmove((char *)new,(char *)REGION_BOXPTR(dstrgn), + dnumRects * sizeof(BoxRec)); + new = REGION_BOXPTR(dstrgn); + } + else + new = REGION_BOXPTR(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(rects, numRects) + 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); +} + +/*- + *----------------------------------------------------------------------- + * miRegionValidate -- + * + * 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 + * miUnion. Maximize the work each miUnion call does by using + * a binary merge. + * + *----------------------------------------------------------------------- + */ + +Bool +miRegionValidate(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 */ + + *pOverlap = FALSE; + if (!badreg->data) + { + good(badreg); + return TRUE; + } + numRects = badreg->data->numRects; + if (!numRects) + { + 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(REGION_BOXPTR(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 */ + Must_have_memory = TRUE; /* XXX */ + ri = (RegionInfo *) xalloc(4 * sizeof(RegionInfo)); + Must_have_memory = FALSE; /* XXX */ + sizeRI = 4; + numRI = 1; + ri[0].prevBand = 0; + ri[0].curBand = 0; + ri[0].reg = *badreg; + box = REGION_BOXPTR(&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 = REGION_END(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(reg, 1); + *REGION_TOP(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(reg, 1); + *REGION_TOP(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; + Must_have_memory = TRUE; /* XXX */ + ri = (RegionInfo *) xrealloc(ri, sizeRI * sizeof(RegionInfo)); + Must_have_memory = FALSE; /* XXX */ + rit = &ri[numRI]; + } + numRI++; + rit->prevBand = 0; + rit->curBand = 0; + rit->reg.extents = *box; + rit->reg.data = (RegDataPtr)NULL; + miRectAlloc(&rit->reg, (i+numRI) / numRI); /* MUST force allocation */ +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 = REGION_END(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; + miRegionOp(reg, reg, hreg, miUnionO, TRUE, TRUE, pOverlap); + 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; + xfree(ri); + good(badreg); + return TRUE; +} + +RegionPtr +miRectsToRegion(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; + + pRgn = miRegionCreate(NullBox, 0); + 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; + } + Must_have_memory = TRUE; /* XXX */ + pData = xallocData(nrects); + pBox = (BoxPtr) (pData + 1); + Must_have_memory = FALSE; /* XXX */ + 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; + miRegionValidate(pRgn, &overlap); + } + else + miSetExtents(pRgn); + good(pRgn); + } + else + { + xfree (pData); + } + return pRgn; +} + +/*====================================================================== + * Region Subtraction + *====================================================================*/ + + +/*- + *----------------------------------------------------------------------- + * miSubtractO -- + * Overlapping band subtraction. x1 is the left-most point not yet + * checked. + * + * Results: + * TRUE if successful. + * + * Side Effects: + * pReg may have rectangles added to it. + * + *----------------------------------------------------------------------- + */ +/*ARGSUSED*/ +static Bool +miSubtractO (pReg, r1, r1End, r2, r2End, y1, y2, pOverlap) + register RegionPtr pReg; + register BoxPtr r1; + BoxPtr r1End; + register BoxPtr r2; + BoxPtr r2End; + register int y1; + int y2; + Bool *pOverlap; +{ + register BoxPtr pNextRect; + register int x1; + + x1 = r1->x1; + + assert(y1x2 <= x1) + { + /* + * Subtrahend entirely to left of minuend: go to next subtrahend. + */ + r2++; + } + else if (r2->x1 <= x1) + { + /* + * Subtrahend preceeds minuend: nuke left edge of minuend. + */ + x1 = r2->x2; + if (x1 >= r1->x2) + { + /* + * Minuend completely covered: advance to next minuend and + * reset left fence to edge of new minuend. + */ + r1++; + if (r1 != r1End) + x1 = r1->x1; + } + else + { + /* + * Subtrahend now used up since it doesn't extend beyond + * minuend + */ + r2++; + } + } + else if (r2->x1 < r1->x2) + { + /* + * Left part of subtrahend covers part of minuend: add uncovered + * part of minuend to region and skip to next subtrahend. + */ + assert(x1x1); + NEWRECT(pReg, pNextRect, x1, y1, r2->x1, y2); + + x1 = r2->x2; + if (x1 >= r1->x2) + { + /* + * Minuend used up: advance to new... + */ + r1++; + if (r1 != r1End) + x1 = r1->x1; + } + else + { + /* + * Subtrahend used up + */ + r2++; + } + } + else + { + /* + * Minuend used up: add any remaining piece before advancing. + */ + if (r1->x2 > x1) + NEWRECT(pReg, pNextRect, x1, y1, r1->x2, y2); + r1++; + if (r1 != r1End) + x1 = r1->x1; + } + } while ((r1 != r1End) && (r2 != r2End)); + + + /* + * Add remaining minuend rectangles to region. + */ + while (r1 != r1End) + { + assert(x1x2); + NEWRECT(pReg, pNextRect, x1, y1, r1->x2, y2); + r1++; + if (r1 != r1End) + x1 = r1->x1; + } + return TRUE; +} + +/*- + *----------------------------------------------------------------------- + * miSubtract -- + * 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. + * + *----------------------------------------------------------------------- + */ +Bool +miSubtract(regD, regM, regS) + register RegionPtr regD; + register RegionPtr regM; + register RegionPtr regS; +{ + Bool overlap; /* result ignored */ + + good(regM); + good(regS); + good(regD); + /* check for trivial rejects */ + if (REGION_NIL(regM) || REGION_NIL(regS) || + !EXTENTCHECK(®M->extents, ®S->extents)) + { + return miRegionCopy(regD, regM); + } + else if (regM == regS) + { + xfreeData(regD); + regD->extents.x2 = regD->extents.x1; + regD->extents.y2 = regD->extents.y1; + regD->data = &miEmptyData; + return TRUE; + } + + /* Add those rectangles in region 1 that aren't in region 2, + do yucky substraction for overlaps, and + just throw away rectangles in region 2 that aren't in region 1 */ + if (!miRegionOp(regD, regM, regS, miSubtractO, TRUE, FALSE, &overlap)) + return FALSE; + + /* + * Can't alter RegD's extents before we call miRegionOp because + * it might be one of the source regions and miRegionOp depends + * on the extents of those regions being unaltered. Besides, this + * way there's no checking against rectangles that will be nuked + * due to coalescing, so we have to examine fewer rectangles. + */ + miSetExtents(regD); + good(regD); + return TRUE; +} + +/*====================================================================== + * Region Inversion + *====================================================================*/ + +/*- + *----------------------------------------------------------------------- + * miInverse -- + * 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. + * + *----------------------------------------------------------------------- + */ +Bool +miInverse(newReg, reg1, invRect) + RegionPtr newReg; /* Destination region */ + RegionPtr reg1; /* Region to invert */ + BoxPtr invRect; /* Bounding box for inversion */ +{ + RegionRec invReg; /* Quick and dirty region made from the + * bounding box */ + Bool overlap; /* result ignored */ + + good(reg1); + good(newReg); + /* check for trivial rejects */ + if (REGION_NIL(reg1) || !EXTENTCHECK(invRect, ®1->extents)) + { + newReg->extents = *invRect; + xfreeData(newReg); + newReg->data = (RegDataPtr)NULL; + return TRUE; + } + + /* Add those rectangles in region 1 that aren't in region 2, + do yucky substraction for overlaps, and + just throw away rectangles in region 2 that aren't in region 1 */ + invReg.extents = *invRect; + invReg.data = (RegDataPtr)NULL; + if (!miRegionOp(newReg, &invReg, reg1, miSubtractO, TRUE, FALSE, &overlap)) + return FALSE; + + /* + * Can't alter newReg's extents before we call miRegionOp because + * it might be one of the source regions and miRegionOp depends + * on the extents of those regions being unaltered. Besides, this + * way there's no checking against rectangles that will be nuked + * due to coalescing, so we have to examine fewer rectangles. + */ + miSetExtents(newReg); + good(newReg); + return TRUE; +} + +/* + * RectIn(region, rect) + * This routine takes a pointer to a region and a pointer to a box + * and determines if the box is outside/inside/partly inside the region. + * + * The idea is to travel through the list of rectangles trying to cover the + * passed box with them. Anytime a piece of the rectangle isn't covered + * by a band of rectangles, partOut is set TRUE. Any time a rectangle in + * the region covers part of the box, partIn is set TRUE. The process ends + * when either the box has been completely covered (we reached a band that + * doesn't overlap the box, partIn is TRUE and partOut is false), the + * box has been partially covered (partIn == partOut == TRUE -- because of + * the banding, the first time this is true we know the box is only + * partially in the region) or is outside the region (we reached a band + * that doesn't overlap the box at all and partIn is false) + */ + +int +miRectIn(region, prect) + register RegionPtr region; + register BoxPtr prect; +{ + register int x; + register int y; + register BoxPtr pbox; + register BoxPtr pboxEnd; + int partIn, partOut; + int numRects; + + good(region); + numRects = REGION_NUM_RECTS(region); + /* useful optimization */ + if (!numRects || !EXTENTCHECK(®ion->extents, prect)) + return(rgnOUT); + + if (numRects == 1) + { + /* We know that it must be rgnIN or rgnPART */ + if (SUBSUMES(®ion->extents, prect)) + return(rgnIN); + else + return(rgnPART); + } + + partOut = FALSE; + partIn = FALSE; + + /* (x,y) starts at upper left of rect, moving to the right and down */ + x = prect->x1; + y = prect->y1; + + /* can stop when both partOut and partIn are TRUE, or we reach prect->y2 */ + for (pbox = REGION_BOXPTR(region), pboxEnd = pbox + numRects; + pbox != pboxEnd; + pbox++) + { + + if (pbox->y2 <= y) + continue; /* getting up to speed or skipping remainder of band */ + + if (pbox->y1 > y) + { + partOut = TRUE; /* missed part of rectangle above */ + if (partIn || (pbox->y1 >= prect->y2)) + break; + y = pbox->y1; /* x guaranteed to be == prect->x1 */ + } + + if (pbox->x2 <= x) + continue; /* not far enough over yet */ + + if (pbox->x1 > x) + { + partOut = TRUE; /* missed part of rectangle to left */ + if (partIn) + break; + } + + if (pbox->x1 < prect->x2) + { + partIn = TRUE; /* definitely overlap */ + if (partOut) + break; + } + + if (pbox->x2 >= prect->x2) + { + y = pbox->y2; /* finished with this band */ + if (y >= prect->y2) + break; + x = prect->x1; /* reset x out to left again */ + } + else + { + /* + * Because boxes in a band are maximal width, if the first box + * to overlap the rectangle doesn't completely cover it in that + * band, the rectangle must be partially out, since some of it + * will be uncovered in that band. partIn will have been set true + * by now... + */ + partOut = TRUE; + break; + } + } + + return(partIn ? ((y < prect->y2) ? rgnPART : rgnIN) : rgnOUT); +} + +/* TranslateRegion(pReg, x, y) + translates in place +*/ + +void +miTranslateRegion(pReg, x, y) + register RegionPtr pReg; + register int x; + register int y; +{ + int x1, x2, y1, y2; + register int nbox; + register BoxPtr pbox; + + good(pReg); + pReg->extents.x1 = x1 = pReg->extents.x1 + x; + pReg->extents.y1 = y1 = pReg->extents.y1 + y; + pReg->extents.x2 = x2 = pReg->extents.x2 + x; + pReg->extents.y2 = y2 = pReg->extents.y2 + y; + if (((x1 - MINSHORT)|(y1 - MINSHORT)|(MAXSHORT - x2)|(MAXSHORT - y2)) >= 0) + { + if (pReg->data && (nbox = pReg->data->numRects)) + { + for (pbox = REGION_BOXPTR(pReg); nbox--; pbox++) + { + pbox->x1 += x; + pbox->y1 += y; + pbox->x2 += x; + pbox->y2 += y; + } + } + return; + } + if (((x2 - MINSHORT)|(y2 - MINSHORT)|(MAXSHORT - x1)|(MAXSHORT - y1)) <= 0) + { + pReg->extents.x2 = pReg->extents.x1; + pReg->extents.y2 = pReg->extents.y1; + xfreeData(pReg); + pReg->data = &miEmptyData; + return; + } + if (x1 < MINSHORT) + pReg->extents.x1 = MINSHORT; + else if (x2 > MAXSHORT) + pReg->extents.x2 = MAXSHORT; + if (y1 < MINSHORT) + pReg->extents.y1 = MINSHORT; + else if (y2 > MAXSHORT) + pReg->extents.y2 = MAXSHORT; + if (pReg->data && (nbox = pReg->data->numRects)) + { + register BoxPtr pboxout; + + for (pboxout = pbox = REGION_BOXPTR(pReg); nbox--; pbox++) + { + pboxout->x1 = x1 = pbox->x1 + x; + pboxout->y1 = y1 = pbox->y1 + y; + pboxout->x2 = x2 = pbox->x2 + x; + pboxout->y2 = y2 = pbox->y2 + y; + if (((x2 - MINSHORT)|(y2 - MINSHORT)| + (MAXSHORT - x1)|(MAXSHORT - y1)) <= 0) + { + pReg->data->numRects--; + continue; + } + if (x1 < MINSHORT) + pboxout->x1 = MINSHORT; + else if (x2 > MAXSHORT) + pboxout->x2 = MAXSHORT; + if (y1 < MINSHORT) + pboxout->y1 = MINSHORT; + else if (y2 > MAXSHORT) + pboxout->y2 = MAXSHORT; + pboxout++; + } + if (pboxout != pbox) + { + if (pReg->data->numRects == 1) + { + pReg->extents = *REGION_BOXPTR(pReg); + xfreeData(pReg); + pReg->data = (RegDataPtr)NULL; + } + else + miSetExtents(pReg); + } + } +} + +void +miRegionReset(pReg, pBox) + RegionPtr pReg; + BoxPtr pBox; +{ + good(pReg); + assert(pBox->x1<=pBox->x2); + assert(pBox->y1<=pBox->y2); + pReg->extents = *pBox; + xfreeData(pReg); + pReg->data = (RegDataPtr)NULL; +} + +Bool +miPointInRegion(pReg, x, y, box) + register RegionPtr pReg; + register int x, y; + BoxPtr box; /* "return" value */ +{ + register BoxPtr pbox, pboxEnd; + int numRects; + + good(pReg); + numRects = REGION_NUM_RECTS(pReg); + if (!numRects || !INBOX(&pReg->extents, x, y)) + return(FALSE); + if (numRects == 1) + { + *box = pReg->extents; + return(TRUE); + } + for (pbox = REGION_BOXPTR(pReg), pboxEnd = pbox + numRects; + pbox != pboxEnd; + pbox++) + { + if (y >= pbox->y2) + continue; /* not there yet */ + if ((y < pbox->y1) || (x < pbox->x1)) + break; /* missed it */ + if (x >= pbox->x2) + continue; /* not there yet */ + *box = *pbox; + return(TRUE); + } + return(FALSE); +} + +Bool +miRegionNotEmpty(pReg) + RegionPtr pReg; +{ + good(pReg); + return(!REGION_NIL(pReg)); +} + + +void +miRegionEmpty(pReg) + RegionPtr pReg; +{ + good(pReg); + xfreeData(pReg); + pReg->extents.x2 = pReg->extents.x1; + pReg->extents.y2 = pReg->extents.y1; + pReg->data = &miEmptyData; +} + +BoxPtr +miRegionExtents(pReg) + RegionPtr pReg; +{ + good(pReg); + return(&pReg->extents); +} + +#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(spans, widths, numSpans) + 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 +miClipSpans(prgnDst, ppt, pwidth, nspans, pptNew, pwidthNew, fSorted) + 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 = REGION_BOXPTR(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 = REGION_NUM_RECTS(prgn); + pbox = REGION_RECTS(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/rfb.h b/rfb.h new file mode 100644 index 0000000..416526d --- /dev/null +++ b/rfb.h @@ -0,0 +1,522 @@ +/* + * rfb.h - header file for RFB DDX implementation. + */ + +/* + * OSXvnc Copyright (C) 2001 Dan McGuirk . + * Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge. + * All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "scrnintstr.h" + +/* trying to replace the above with some more minimal set of includes */ +#include "misc.h" +#include "Xmd.h" +#include "regionstr.h" +#include + +#include +#include +#include +#ifdef HAVE_PTHREADS +#include +#endif +#ifdef __linux__ +#include +#else +#include +#endif + +#ifndef _BYTE_ORDER +#define _BYTE_ORDER __BYTE_ORDER +#endif + +#ifndef _LITTLE_ENDIAN +#define _LITTLE_ENDIAN __LITTLE_ENDIAN +#endif + +#define MAX_ENCODINGS 10 + +#ifdef HAVE_PTHREADS +#define IF_PTHREADS(x) (x) +#else +#define IF_PTHREADS(x) +#endif + +struct rfbClientRec; +//typedef struct rfbClientInfo* rfbClientPtr; +typedef void (*KbdAddEventProcPtr) (Bool down, KeySym keySym, struct rfbClientRec* cl); +typedef void (*KbdReleaseAllKeysProcPtr) (struct rfbClientRec* cl); +typedef void (*PtrAddEventProcPtr) (int buttonMask, int x, int y, struct rfbClientRec* cl); +typedef void (*SetXCutTextProcPtr) (char* str,int len, struct rfbClientRec* cl); + +/* + * Per-screen (framebuffer) structure. There is only one of these, since we + * don't allow the X server to have multiple screens. + */ + +typedef struct +{ + int width; + int paddedWidthInBytes; + int height; + int depth; + int bitsPerPixel; + int sizeInBytes; + + Pixel blackPixel; + Pixel whitePixel; + + /* The following two members are used to minimise the amount of unnecessary + drawing caused by cursor movement. Whenever any drawing affects the + part of the screen where the cursor is, the cursor is removed first and + then the drawing is done (this is what the sprite routines test for). + Afterwards, however, we do not replace the cursor, even when the cursor + is logically being moved across the screen. We only draw the cursor + again just as we are about to send the client a framebuffer update. + + We need to be careful when removing and drawing the cursor because of + their relationship with the normal drawing routines. The drawing + routines can invoke the cursor routines, but also the cursor routines + themselves end up invoking drawing routines. + + Removing the cursor (rfbSpriteRemoveCursor) is eventually achieved by + doing a CopyArea from a pixmap to the screen, where the pixmap contains + the saved contents of the screen under the cursor. Before doing this, + however, we set cursorIsDrawn to FALSE. Then, when CopyArea is called, + it sees that cursorIsDrawn is FALSE and so doesn't feel the need to + (recursively!) remove the cursor before doing it. + + Putting up the cursor (rfbSpriteRestoreCursor) involves a call to + PushPixels. While this is happening, cursorIsDrawn must be FALSE so + that PushPixels doesn't think it has to remove the cursor first. + Obviously cursorIsDrawn is set to TRUE afterwards. + + Another problem we face is that drawing routines sometimes cause a + framebuffer update to be sent to the RFB client. When the RFB client is + already waiting for a framebuffer update and some drawing to the + framebuffer then happens, the drawing routine sees that the client is + ready, so it calls rfbSendFramebufferUpdate. If the cursor is not drawn + at this stage, it must be put up, and so rfbSpriteRestoreCursor is + called. However, if the original drawing routine was actually called + from within rfbSpriteRestoreCursor or rfbSpriteRemoveCursor we don't + want this to happen. So both the cursor routines set + dontSendFramebufferUpdate to TRUE, and all the drawing routines check + this before calling rfbSendFramebufferUpdate. */ + + Bool cursorIsDrawn; /* TRUE if the cursor is currently drawn */ + Bool dontSendFramebufferUpdate; /* TRUE while removing or drawing the + cursor */ + + /* wrapped screen functions */ + + CloseScreenProcPtr CloseScreen; + CreateGCProcPtr CreateGC; + PaintWindowBackgroundProcPtr PaintWindowBackground; + PaintWindowBorderProcPtr PaintWindowBorder; + CopyWindowProcPtr CopyWindow; + ClearToBackgroundProcPtr ClearToBackground; + RestoreAreasProcPtr RestoreAreas; + + /* additions by libvncserver */ + + ScreenRec screen; + rfbPixelFormat rfbServerFormat; + char* desktopName; + char rfbThisHost[255]; + int rfbPort; + Bool socketInitDone; + int inetdSock; + int maxSock; + int maxFd; + int rfbListenSock; + int udpPort; + int udpSock; + Bool udpSockConnected; + struct sockaddr_in udpRemoteAddr; + Bool inetdInitDone; + fd_set allFds; + int rfbMaxClientWait; + char* rfbAuthPasswdFile; + int rfbDeferUpdateTime; + char* rfbScreen; + Bool rfbAlwaysShared; + Bool rfbNeverShared; + Bool rfbDontDisconnect; + struct rfbClientRec* rfbClientHead; + + /* the following members have to be supplied by the serving process */ + char* frameBuffer; + KbdAddEventProcPtr kbdAddEvent; + KbdReleaseAllKeysProcPtr kbdReleaseAllKeys; + PtrAddEventProcPtr ptrAddEvent; + SetXCutTextProcPtr setXCutText; +} rfbScreenInfo, *rfbScreenInfoPtr; + + +/* + * rfbTranslateFnType is the type of translation functions. + */ + +struct rfbClientRec; +typedef void (*rfbTranslateFnType)(char *table, rfbPixelFormat *in, + rfbPixelFormat *out, + char *iptr, char *optr, + int bytesBetweenInputLines, + int width, int height); + + +/* + * Per-client structure. + */ + +typedef struct rfbClientRec { + rfbScreenInfoPtr screen; + + int sock; + char *host; +#ifdef HAVE_PTHREADS + pthread_mutex_t outputMutex; +#endif + /* Possible client states: */ + enum { + RFB_PROTOCOL_VERSION, /* establishing protocol version */ + RFB_AUTHENTICATION, /* authenticating */ + RFB_INITIALISATION, /* sending initialisation messages */ + RFB_NORMAL /* normal protocol messages */ + } state; + + Bool reverseConnection; + + Bool readyForSetColourMapEntries; + + Bool useCopyRect; + int preferredEncoding; + int correMaxWidth, correMaxHeight; + + /* The following member is only used during VNC authentication */ + + CARD8 authChallenge[CHALLENGESIZE]; + + /* The following members represent the update needed to get the client's + framebuffer from its present state to the current state of our + framebuffer. + + If the client does not accept CopyRect encoding then the update is + simply represented as the region of the screen which has been modified + (modifiedRegion). + + If the client does accept CopyRect encoding, then the update consists of + two parts. First we have a single copy from one region of the screen to + another (the destination of the copy is copyRegion), and second we have + the region of the screen which has been modified in some other way + (modifiedRegion). + + Although the copy is of a single region, this region may have many + rectangles. When sending an update, the copyRegion is always sent + before the modifiedRegion. This is because the modifiedRegion may + overlap parts of the screen which are in the source of the copy. + + In fact during normal processing, the modifiedRegion may even overlap + the destination copyRegion. Just before an update is sent we remove + from the copyRegion anything in the modifiedRegion. */ + + RegionRec copyRegion; /* the destination region of the copy */ + int copyDX, copyDY; /* the translation by which the copy happens */ + + +#ifdef HAVE_PTHREADS + pthread_mutex_t updateMutex; + pthread_cond_t updateCond; +#endif + + RegionRec modifiedRegion; + + /* As part of the FramebufferUpdateRequest, a client can express interest + in a subrectangle of the whole framebuffer. This is stored in the + requestedRegion member. In the normal case this is the whole + framebuffer if the client is ready, empty if it's not. */ + + RegionRec requestedRegion; + + /* The following members represent the state of the "deferred update" timer + - when the framebuffer is modified and the client is ready, in most + cases it is more efficient to defer sending the update by a few + milliseconds so that several changes to the framebuffer can be combined + into a single update. */ + + Bool deferredUpdateScheduled; + OsTimerPtr deferredUpdateTimer; + + /* translateFn points to the translation function which is used to copy + and translate a rectangle from the framebuffer to an output buffer. */ + + rfbTranslateFnType translateFn; + + char *translateLookupTable; + + rfbPixelFormat format; + +/* + * UPDATE_BUF_SIZE must be big enough to send at least one whole line of the + * framebuffer. So for a max screen width of say 2K with 32-bit pixels this + * means 8K minimum. + */ + +#define UPDATE_BUF_SIZE 30000 + + char updateBuf[UPDATE_BUF_SIZE]; + int ublen; + + /* statistics */ + + int rfbBytesSent[MAX_ENCODINGS]; + int rfbRectanglesSent[MAX_ENCODINGS]; + int rfbLastRectMarkersSent; + int rfbLastRectBytesSent; + int rfbCursorBytesSent; + int rfbCursorUpdatesSent; + int rfbFramebufferUpdateMessagesSent; + int rfbRawBytesEquivalent; + int rfbKeyEventsRcvd; + int rfbPointerEventsRcvd; + + /* zlib encoding -- necessary compression state info per client */ + + struct z_stream_s compStream; + Bool compStreamInited; + + CARD32 zlibCompressLevel; + + /* tight encoding -- preserve zlib streams' state for each client */ + + z_stream zsStruct[4]; + Bool zsActive[4]; + int zsLevel[4]; + int tightCompressLevel; + int tightQualityLevel; + + Bool enableLastRectEncoding; /* client supports LastRect encoding */ + Bool enableCursorShapeUpdates; /* client supports cursor shape updates */ + Bool useRichCursorEncoding; /* rfbEncodingRichCursor is preferred */ + Bool cursorWasChanged; /* cursor shape update should be sent */ + + struct rfbClientRec *prev; + struct rfbClientRec *next; + +} rfbClientRec, *rfbClientPtr; + + +/* + * This macro is used to test whether there is a framebuffer update needing to + * be sent to the client. + */ + +#define FB_UPDATE_PENDING(cl) \ + ((!(cl)->enableCursorShapeUpdates && !(cl)->screen->cursorIsDrawn) || \ + ((cl)->enableCursorShapeUpdates && (cl)->cursorWasChanged) || \ + REGION_NOTEMPTY(&((cl)->screenInfo->screen),&(cl)->copyRegion) || \ + REGION_NOTEMPTY(&((cl)->screenInfo->screen),&(cl)->modifiedRegion)) + +/* + * This macro creates an empty region (ie. a region with no areas) if it is + * given a rectangle with a width or height of zero. It appears that + * REGION_INTERSECT does not quite do the right thing with zero-width + * rectangles, but it should with completely empty regions. + */ + +#define SAFE_REGION_INIT(pscreen, preg, rect, size) \ +{ \ + if ( ( (rect) ) && \ + ( ( (rect)->x2 == (rect)->x1 ) || \ + ( (rect)->y2 == (rect)->y1 ) ) ) { \ + REGION_INIT( (pscreen), (preg), NullBox, 0 ); \ + } else { \ + REGION_INIT( (pscreen), (preg), (rect), (size) ); \ + } \ +} + + +/* + * Macros for endian swapping. + */ + +#define Swap16(s) ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff)) + +#define Swap32(l) (((l) >> 24) | \ + (((l) & 0x00ff0000) >> 8) | \ + (((l) & 0x0000ff00) << 8) | \ + ((l) << 24)) + + +static const int rfbEndianTest = (_BYTE_ORDER == _LITTLE_ENDIAN); + +#define Swap16IfLE(s) (*(const char *)&rfbEndianTest ? Swap16(s) : (s)) + +#define Swap32IfLE(l) (*(const char *)&rfbEndianTest ? Swap32(l) : (l)) + +/* main.c */ + +extern void rfbLog(char *format, ...); +extern void rfbLogPerror(char *str); +extern int runVNCServer(int argc, char *argv[]); + + +/* sockets.c */ + +extern int rfbMaxClientWait; + +extern void rfbCloseClient(rfbClientPtr cl); +extern int ReadExact(rfbClientPtr cl, char *buf, int len); +extern int WriteExact(rfbClientPtr cl, char *buf, int len); +extern void rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec); +extern int ListenOnTCPPort(int port); +extern int ListenOnUDPPort(int port); + +/* rfbserver.c */ + +extern rfbClientPtr pointerClient; + + +/* Routines to iterate over the client list in a thread-safe way. + Only a single iterator can be in use at a time process-wide. */ +typedef struct rfbClientIterator *rfbClientIteratorPtr; + +extern void rfbClientListInit(rfbScreenInfoPtr rfbScreen); +extern rfbClientIteratorPtr rfbGetClientIterator(rfbScreenInfoPtr rfbScreen); +extern rfbClientPtr rfbClientIteratorNext(rfbClientIteratorPtr iterator); +extern void rfbReleaseClientIterator(rfbClientIteratorPtr iterator); + +extern void rfbNewClientConnection(rfbScreenInfoPtr rfbScreen,int sock); +extern rfbClientPtr rfbNewClient(rfbScreenInfoPtr rfbScreen,int sock); +extern rfbClientPtr rfbReverseConnection(char *host, int port); +extern void rfbClientConnectionGone(rfbClientPtr cl); +extern void rfbProcessClientMessage(rfbClientPtr cl); +extern void rfbClientConnFailed(rfbClientPtr cl, char *reason); +extern void rfbNewUDPConnection(rfbScreenInfoPtr rfbScreen,int sock); +extern void rfbProcessUDPInput(rfbClientPtr cl); +extern Bool rfbSendFramebufferUpdate(rfbClientPtr cl, RegionRec updateRegion); +extern Bool rfbSendRectEncodingRaw(rfbClientPtr cl, int x,int y,int w,int h); +extern Bool rfbSendUpdateBuf(rfbClientPtr cl); +extern void rfbSendServerCutText(rfbScreenInfoPtr rfbScreen,char *str, int len); + +void rfbGotXCutText(rfbScreenInfoPtr rfbScreen, char *str, int len); + +/* translate.c */ + +extern Bool rfbEconomicTranslate; + +extern void rfbTranslateNone(char *table, rfbPixelFormat *in, + rfbPixelFormat *out, + char *iptr, char *optr, + int bytesBetweenInputLines, + int width, int height); +extern Bool rfbSetTranslateFunction(rfbClientPtr cl); + + +/* httpd.c */ + +extern int httpPort; +extern char *httpDir; + +extern void httpInitSockets(); +extern void httpCheckFds(); + + + +/* auth.c */ + +extern char *rfbAuthPasswdFile; +extern Bool rfbAuthenticating; + +extern void rfbAuthNewClient(rfbClientPtr cl); +extern void rfbAuthProcessClientMessage(rfbClientPtr cl); + + +/* rre.c */ + +extern Bool rfbSendRectEncodingRRE(rfbClientPtr cl, int x,int y,int w,int h); + + +/* corre.c */ + +extern Bool rfbSendRectEncodingCoRRE(rfbClientPtr cl, int x,int y,int w,int h); + + +/* hextile.c */ + +extern Bool rfbSendRectEncodingHextile(rfbClientPtr cl, int x, int y, int w, + int h); + + +/* zlib.c */ + +/* Minimum zlib rectangle size in bytes. Anything smaller will + * not compress well due to overhead. + */ +#define VNC_ENCODE_ZLIB_MIN_COMP_SIZE (17) + +/* Set maximum zlib rectangle size in pixels. Always allow at least + * two scan lines. + */ +#define ZLIB_MAX_RECT_SIZE (128*256) +#define ZLIB_MAX_SIZE(min) ((( min * 2 ) > ZLIB_MAX_RECT_SIZE ) ? \ + ( min * 2 ) : ZLIB_MAX_RECT_SIZE ) + +extern Bool rfbSendRectEncodingZlib(rfbClientPtr cl, int x, int y, int w, + int h); + + +/* tight.c */ + +#define TIGHT_DEFAULT_COMPRESSION 6 + +extern Bool rfbTightDisableGradient; + +extern int rfbNumCodedRectsTight(rfbClientPtr cl, int x,int y,int w,int h); +extern Bool rfbSendRectEncodingTight(rfbClientPtr cl, int x,int y,int w,int h); + + +/* cursor.c */ + +extern Bool rfbSendCursorShape(rfbClientPtr cl, ScreenPtr pScreen); + + +/* stats.c */ + +extern void rfbResetStats(rfbClientPtr cl); +extern void rfbPrintStats(rfbClientPtr cl); + +extern void rfbInitSockets(rfbScreenInfoPtr rfbScreen); +extern void rfbDisconnectUDPSock(rfbScreenInfoPtr cl); + +void rfbMarkRectAsModified(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2); +void rfbMarkRegionAsModified(rfbScreenInfoPtr rfbScreen,RegionPtr modRegion); + + +/* functions to make a vnc server */ +extern rfbScreenInfoPtr rfbDefaultScreenInit(int argc,char** argv); +extern void rfbScreenCleanup(rfbScreenInfoPtr screenInfo); + +/* call one of these two functions to service the vnc clients. + usec are the microseconds the select on the fds waits. + if you are using the event loop, set this to some value > 0. */ + +extern void runEventLoop(rfbScreenInfoPtr screenInfo, long usec, Bool runInBackground); +extern void processEvents(rfbScreenInfoPtr screenInfo,long usec); diff --git a/rfbproto.h b/rfbproto.h new file mode 100644 index 0000000..5ef1d90 --- /dev/null +++ b/rfbproto.h @@ -0,0 +1,785 @@ +/* + * Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved. + * Copyright (C) 2000 Tridia Corporation. All Rights Reserved. + * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * rfbproto.h - header file for the RFB protocol version 3.3 + * + * Uses types CARD for an n-bit unsigned integer, INT for an n-bit signed + * integer (for n = 8, 16 and 32). + * + * All multiple byte integers are in big endian (network) order (most + * significant byte first). Unless noted otherwise there is no special + * alignment of protocol structures. + * + * + * Once the initial handshaking is done, all messages start with a type byte, + * (usually) followed by message-specific data. The order of definitions in + * this file is as follows: + * + * (1) Structures used in several types of message. + * (2) Structures used in the initial handshaking. + * (3) Message types. + * (4) Encoding types. + * (5) For each message type, the form of the data following the type byte. + * Sometimes this is defined by a single structure but the more complex + * messages have to be explained by comments. + */ + + +/***************************************************************************** + * + * Structures used in several messages + * + *****************************************************************************/ + +/*----------------------------------------------------------------------------- + * Structure used to specify a rectangle. This structure is a multiple of 4 + * bytes so that it can be interspersed with 32-bit pixel data without + * affecting alignment. + */ + +typedef struct { + CARD16 x; + CARD16 y; + CARD16 w; + CARD16 h; +} rfbRectangle; + +#define sz_rfbRectangle 8 + + +/*----------------------------------------------------------------------------- + * Structure used to specify pixel format. + */ + +typedef struct { + + CARD8 bitsPerPixel; /* 8,16,32 only */ + + CARD8 depth; /* 8 to 32 */ + + CARD8 bigEndian; /* True if multi-byte pixels are interpreted + as big endian, or if single-bit-per-pixel + has most significant bit of the byte + corresponding to first (leftmost) pixel. Of + course this is meaningless for 8 bits/pix */ + + CARD8 trueColour; /* If false then we need a "colour map" to + convert pixels to RGB. If true, xxxMax and + xxxShift specify bits used for red, green + and blue */ + + /* the following fields are only meaningful if trueColour is true */ + + CARD16 redMax; /* maximum red value (= 2^n - 1 where n is the + number of bits used for red). Note this + value is always in big endian order. */ + + CARD16 greenMax; /* similar for green */ + + CARD16 blueMax; /* and blue */ + + CARD8 redShift; /* number of shifts needed to get the red + value in a pixel to the least significant + bit. To find the red value from a given + pixel, do the following: + 1) Swap pixel value according to bigEndian + (e.g. if bigEndian is false and host byte + order is big endian, then swap). + 2) Shift right by redShift. + 3) AND with redMax (in host byte order). + 4) You now have the red value between 0 and + redMax. */ + + CARD8 greenShift; /* similar for green */ + + CARD8 blueShift; /* and blue */ + + CARD8 pad1; + CARD16 pad2; + +} rfbPixelFormat; + +#define sz_rfbPixelFormat 16 + + + +/***************************************************************************** + * + * Initial handshaking messages + * + *****************************************************************************/ + +/*----------------------------------------------------------------------------- + * Protocol Version + * + * The server always sends 12 bytes to start which identifies the latest RFB + * protocol version number which it supports. These bytes are interpreted + * as a string of 12 ASCII characters in the format "RFB xxx.yyy\n" where + * xxx and yyy are the major and minor version numbers (for version 3.3 + * this is "RFB 003.003\n"). + * + * The client then replies with a similar 12-byte message giving the version + * number of the protocol which should actually be used (which may be different + * to that quoted by the server). + * + * It is intended that both clients and servers may provide some level of + * backwards compatibility by this mechanism. Servers in particular should + * attempt to provide backwards compatibility, and even forwards compatibility + * to some extent. For example if a client demands version 3.1 of the + * protocol, a 3.0 server can probably assume that by ignoring requests for + * encoding types it doesn't understand, everything will still work OK. This + * will probably not be the case for changes in the major version number. + * + * The format string below can be used in sprintf or sscanf to generate or + * decode the version string respectively. + */ + +#define rfbProtocolVersionFormat "RFB %03d.%03d\n" +#define rfbProtocolMajorVersion 3 +#define rfbProtocolMinorVersion 3 + +typedef char rfbProtocolVersionMsg[13]; /* allow extra byte for null */ + +#define sz_rfbProtocolVersionMsg 12 + + +/*----------------------------------------------------------------------------- + * Authentication + * + * Once the protocol version has been decided, the server then sends a 32-bit + * word indicating whether any authentication is needed on the connection. + * The value of this word determines the authentication scheme in use. For + * version 3.0 of the protocol this may have one of the following values: + */ + +#define rfbConnFailed 0 +#define rfbNoAuth 1 +#define rfbVncAuth 2 + +/* + * rfbConnFailed: For some reason the connection failed (e.g. the server + * cannot support the desired protocol version). This is + * followed by a string describing the reason (where a + * string is specified as a 32-bit length followed by that + * many ASCII characters). + * + * rfbNoAuth: No authentication is needed. + * + * rfbVncAuth: The VNC authentication scheme is to be used. A 16-byte + * challenge follows, which the client encrypts as + * appropriate using the password and sends the resulting + * 16-byte response. If the response is correct, the + * server sends the 32-bit word rfbVncAuthOK. If a simple + * failure happens, the server sends rfbVncAuthFailed and + * closes the connection. If the server decides that too + * many failures have occurred, it sends rfbVncAuthTooMany + * and closes the connection. In the latter case, the + * server should not allow an immediate reconnection by + * the client. + */ + +#define rfbVncAuthOK 0 +#define rfbVncAuthFailed 1 +#define rfbVncAuthTooMany 2 + + +/*----------------------------------------------------------------------------- + * Client Initialisation Message + * + * Once the client and server are sure that they're happy to talk to one + * another, the client sends an initialisation message. At present this + * message only consists of a boolean indicating whether the server should try + * to share the desktop by leaving other clients connected, or give exclusive + * access to this client by disconnecting all other clients. + */ + +typedef struct { + CARD8 shared; +} rfbClientInitMsg; + +#define sz_rfbClientInitMsg 1 + + +/*----------------------------------------------------------------------------- + * Server Initialisation Message + * + * After the client initialisation message, the server sends one of its own. + * This tells the client the width and height of the server's framebuffer, + * its pixel format and the name associated with the desktop. + */ + +typedef struct { + CARD16 framebufferWidth; + CARD16 framebufferHeight; + rfbPixelFormat format; /* the server's preferred pixel format */ + CARD32 nameLength; + /* followed by char name[nameLength] */ +} rfbServerInitMsg; + +#define sz_rfbServerInitMsg (8 + sz_rfbPixelFormat) + + +/* + * Following the server initialisation message it's up to the client to send + * whichever protocol messages it wants. Typically it will send a + * SetPixelFormat message and a SetEncodings message, followed by a + * FramebufferUpdateRequest. From then on the server will send + * FramebufferUpdate messages in response to the client's + * FramebufferUpdateRequest messages. The client should send + * FramebufferUpdateRequest messages with incremental set to true when it has + * finished processing one FramebufferUpdate and is ready to process another. + * With a fast client, the rate at which FramebufferUpdateRequests are sent + * should be regulated to avoid hogging the network. + */ + + + +/***************************************************************************** + * + * Message types + * + *****************************************************************************/ + +/* server -> client */ + +#define rfbFramebufferUpdate 0 +#define rfbSetColourMapEntries 1 +#define rfbBell 2 +#define rfbServerCutText 3 + + +/* client -> server */ + +#define rfbSetPixelFormat 0 +#define rfbFixColourMapEntries 1 /* not currently supported */ +#define rfbSetEncodings 2 +#define rfbFramebufferUpdateRequest 3 +#define rfbKeyEvent 4 +#define rfbPointerEvent 5 +#define rfbClientCutText 6 + + + + +/***************************************************************************** + * + * Encoding types + * + *****************************************************************************/ + +#define rfbEncodingRaw 0 +#define rfbEncodingCopyRect 1 +#define rfbEncodingRRE 2 +#define rfbEncodingCoRRE 4 +#define rfbEncodingHextile 5 +#define rfbEncodingZlib 6 +#define rfbEncodingTight 7 +#define rfbEncodingZlibHex 8 + +/* + * Special encoding numbers: + * 0xFFFFFF00 .. 0xFFFFFF0F -- encoding-specific compression levels; + * 0xFFFFFF10 .. 0xFFFFFF1F -- mouse cursor shape data; + * 0xFFFFFF20 .. 0xFFFFFF2F -- various protocol extensions; + * 0xFFFFFF30 .. 0xFFFFFFDF -- not allocated yet; + * 0xFFFFFFE0 .. 0xFFFFFFEF -- quality level for JPEG compressor; + * 0xFFFFFFF0 .. 0xFFFFFFFF -- cross-encoding compression levels. + */ + +#define rfbEncodingCompressLevel0 0xFFFFFF00 +#define rfbEncodingCompressLevel1 0xFFFFFF01 +#define rfbEncodingCompressLevel2 0xFFFFFF02 +#define rfbEncodingCompressLevel3 0xFFFFFF03 +#define rfbEncodingCompressLevel4 0xFFFFFF04 +#define rfbEncodingCompressLevel5 0xFFFFFF05 +#define rfbEncodingCompressLevel6 0xFFFFFF06 +#define rfbEncodingCompressLevel7 0xFFFFFF07 +#define rfbEncodingCompressLevel8 0xFFFFFF08 +#define rfbEncodingCompressLevel9 0xFFFFFF09 + +#define rfbEncodingXCursor 0xFFFFFF10 +#define rfbEncodingRichCursor 0xFFFFFF11 + +#define rfbEncodingLastRect 0xFFFFFF20 + +#define rfbEncodingQualityLevel0 0xFFFFFFE0 +#define rfbEncodingQualityLevel1 0xFFFFFFE1 +#define rfbEncodingQualityLevel2 0xFFFFFFE2 +#define rfbEncodingQualityLevel3 0xFFFFFFE3 +#define rfbEncodingQualityLevel4 0xFFFFFFE4 +#define rfbEncodingQualityLevel5 0xFFFFFFE5 +#define rfbEncodingQualityLevel6 0xFFFFFFE6 +#define rfbEncodingQualityLevel7 0xFFFFFFE7 +#define rfbEncodingQualityLevel8 0xFFFFFFE8 +#define rfbEncodingQualityLevel9 0xFFFFFFE9 + + +/***************************************************************************** + * + * Server -> client message definitions + * + *****************************************************************************/ + + +/*----------------------------------------------------------------------------- + * FramebufferUpdate - a block of rectangles to be copied to the framebuffer. + * + * This message consists of a header giving the number of rectangles of pixel + * data followed by the rectangles themselves. The header is padded so that + * together with the type byte it is an exact multiple of 4 bytes (to help + * with alignment of 32-bit pixels): + */ + +typedef struct { + CARD8 type; /* always rfbFramebufferUpdate */ + CARD8 pad; + CARD16 nRects; + /* followed by nRects rectangles */ +} rfbFramebufferUpdateMsg; + +#define sz_rfbFramebufferUpdateMsg 4 + +/* + * Each rectangle of pixel data consists of a header describing the position + * and size of the rectangle and a type word describing the encoding of the + * pixel data, followed finally by the pixel data. Note that if the client has + * not sent a SetEncodings message then it will only receive raw pixel data. + * Also note again that this structure is a multiple of 4 bytes. + */ + +typedef struct { + rfbRectangle r; + CARD32 encoding; /* one of the encoding types rfbEncoding... */ +} rfbFramebufferUpdateRectHeader; + +#define sz_rfbFramebufferUpdateRectHeader (sz_rfbRectangle + 4) + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * Raw Encoding. Pixels are sent in top-to-bottom scanline order, + * left-to-right within a scanline with no padding in between. + */ + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * CopyRect Encoding. The pixels are specified simply by the x and y position + * of the source rectangle. + */ + +typedef struct { + CARD16 srcX; + CARD16 srcY; +} rfbCopyRect; + +#define sz_rfbCopyRect 4 + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * RRE - Rise-and-Run-length Encoding. We have an rfbRREHeader structure + * giving the number of subrectangles following. Finally the data follows in + * the form [...] where each is + * []. + */ + +typedef struct { + CARD32 nSubrects; +} rfbRREHeader; + +#define sz_rfbRREHeader 4 + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * CoRRE - Compact RRE Encoding. We have an rfbRREHeader structure giving + * the number of subrectangles following. Finally the data follows in the form + * [...] where each is + * []. This means that + * the whole rectangle must be at most 255x255 pixels. + */ + +typedef struct { + CARD8 x; + CARD8 y; + CARD8 w; + CARD8 h; +} rfbCoRRERectangle; + +#define sz_rfbCoRRERectangle 4 + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * Hextile Encoding. The rectangle is divided up into "tiles" of 16x16 pixels, + * starting at the top left going in left-to-right, top-to-bottom order. If + * the width of the rectangle is not an exact multiple of 16 then the width of + * the last tile in each row will be correspondingly smaller. Similarly if the + * height is not an exact multiple of 16 then the height of each tile in the + * final row will also be smaller. Each tile begins with a "subencoding" type + * byte, which is a mask made up of a number of bits. If the Raw bit is set + * then the other bits are irrelevant; w*h pixel values follow (where w and h + * are the width and height of the tile). Otherwise the tile is encoded in a + * similar way to RRE, except that the position and size of each subrectangle + * can be specified in just two bytes. The other bits in the mask are as + * follows: + * + * BackgroundSpecified - if set, a pixel value follows which specifies + * the background colour for this tile. The first non-raw tile in a + * rectangle must have this bit set. If this bit isn't set then the + * background is the same as the last tile. + * + * ForegroundSpecified - if set, a pixel value follows which specifies + * the foreground colour to be used for all subrectangles in this tile. + * If this bit is set then the SubrectsColoured bit must be zero. + * + * AnySubrects - if set, a single byte follows giving the number of + * subrectangles following. If not set, there are no subrectangles (i.e. + * the whole tile is just solid background colour). + * + * SubrectsColoured - if set then each subrectangle is preceded by a pixel + * value giving the colour of that subrectangle. If not set, all + * subrectangles are the same colour, the foreground colour; if the + * ForegroundSpecified bit wasn't set then the foreground is the same as + * the last tile. + * + * The position and size of each subrectangle is specified in two bytes. The + * Pack macros below can be used to generate the two bytes from x, y, w, h, + * and the Extract macros can be used to extract the x, y, w, h values from + * the two bytes. + */ + +#define rfbHextileRaw (1 << 0) +#define rfbHextileBackgroundSpecified (1 << 1) +#define rfbHextileForegroundSpecified (1 << 2) +#define rfbHextileAnySubrects (1 << 3) +#define rfbHextileSubrectsColoured (1 << 4) + +#define rfbHextilePackXY(x,y) (((x) << 4) | (y)) +#define rfbHextilePackWH(w,h) ((((w)-1) << 4) | ((h)-1)) +#define rfbHextileExtractX(byte) ((byte) >> 4) +#define rfbHextileExtractY(byte) ((byte) & 0xf) +#define rfbHextileExtractW(byte) (((byte) >> 4) + 1) +#define rfbHextileExtractH(byte) (((byte) & 0xf) + 1) + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * zlib - zlib compressed Encoding. We have an rfbZlibHeader structure + * giving the number of bytes following. Finally the data follows is + * zlib compressed version of the raw pixel data as negotiated. + */ + +typedef struct { + CARD32 nBytes; +} rfbZlibHeader; + +#define sz_rfbZlibHeader 4 + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * Tight Encoding. FIXME: Add more documentation. + */ + +#define rfbTightExplicitFilter 0x04 +#define rfbTightFill 0x08 +#define rfbTightJpeg 0x09 +#define rfbTightMaxSubencoding 0x09 + +/* Filters to improve compression efficiency */ +#define rfbTightFilterCopy 0x00 +#define rfbTightFilterPalette 0x01 +#define rfbTightFilterGradient 0x02 + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * XCursor encoding. This is a special encoding used to transmit X-style + * cursor shapes from server to clients. Note that for this encoding, + * coordinates in rfbFramebufferUpdateRectHeader structure hold hotspot + * position (r.x, r.y) and cursor size (r.w, r.h). If (w * h != 0), two RGB + * samples are sent after header in the rfbXCursorColors structure. They + * denote foreground and background colors of the cursor. If a client + * supports only black-and-white cursors, it should ignore these colors and + * assume that foreground is black and background is white. Next, two bitmaps + * (1 bits per pixel) follow: first one with actual data (value 0 denotes + * background color, value 1 denotes foreground color), second one with + * transparency data (bits with zero value mean that these pixels are + * transparent). Both bitmaps represent cursor data in a byte stream, from + * left to right, from top to bottom, and each row is byte-aligned. Most + * significant bits correspond to leftmost pixels. The number of bytes in + * each row can be calculated as ((w + 7) / 8). If (w * h == 0), cursor + * should be hidden (or default local cursor should be set by the client). + */ + +typedef struct { + CARD8 foreRed; + CARD8 foreGreen; + CARD8 foreBlue; + CARD8 backRed; + CARD8 backGreen; + CARD8 backBlue; +} rfbXCursorColors; + +#define sz_rfbXCursorColors 6 + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * RichCursor encoding. This is a special encoding used to transmit cursor + * shapes from server to clients. It is similar to the XCursor encoding but + * uses client pixel format instead of two RGB colors to represent cursor + * image. For this encoding, coordinates in rfbFramebufferUpdateRectHeader + * structure hold hotspot position (r.x, r.y) and cursor size (r.w, r.h). + * After header, two pixmaps follow: first one with cursor image in current + * client pixel format (like in raw encoding), second with transparency data + * (1 bit per pixel, exactly the same format as used for transparency bitmap + * in the XCursor encoding). If (w * h == 0), cursor should be hidden (or + * default local cursor should be set by the client). + */ + + +/*----------------------------------------------------------------------------- + * SetColourMapEntries - these messages are only sent if the pixel + * format uses a "colour map" (i.e. trueColour false) and the client has not + * fixed the entire colour map using FixColourMapEntries. In addition they + * will only start being sent after the client has sent its first + * FramebufferUpdateRequest. So if the client always tells the server to use + * trueColour then it never needs to process this type of message. + */ + +typedef struct { + CARD8 type; /* always rfbSetColourMapEntries */ + CARD8 pad; + CARD16 firstColour; + CARD16 nColours; + + /* Followed by nColours * 3 * CARD16 + r1, g1, b1, r2, g2, b2, r3, g3, b3, ..., rn, bn, gn */ + +} rfbSetColourMapEntriesMsg; + +#define sz_rfbSetColourMapEntriesMsg 6 + + + +/*----------------------------------------------------------------------------- + * Bell - ring a bell on the client if it has one. + */ + +typedef struct { + CARD8 type; /* always rfbBell */ +} rfbBellMsg; + +#define sz_rfbBellMsg 1 + + + +/*----------------------------------------------------------------------------- + * ServerCutText - the server has new text in its cut buffer. + */ + +typedef struct { + CARD8 type; /* always rfbServerCutText */ + CARD8 pad1; + CARD16 pad2; + CARD32 length; + /* followed by char text[length] */ +} rfbServerCutTextMsg; + +#define sz_rfbServerCutTextMsg 8 + + +/*----------------------------------------------------------------------------- + * Union of all server->client messages. + */ + +typedef union { + CARD8 type; + rfbFramebufferUpdateMsg fu; + rfbSetColourMapEntriesMsg scme; + rfbBellMsg b; + rfbServerCutTextMsg sct; +} rfbServerToClientMsg; + + + +/***************************************************************************** + * + * Message definitions (client -> server) + * + *****************************************************************************/ + + +/*----------------------------------------------------------------------------- + * SetPixelFormat - tell the RFB server the format in which the client wants + * pixels sent. + */ + +typedef struct { + CARD8 type; /* always rfbSetPixelFormat */ + CARD8 pad1; + CARD16 pad2; + rfbPixelFormat format; +} rfbSetPixelFormatMsg; + +#define sz_rfbSetPixelFormatMsg (sz_rfbPixelFormat + 4) + + +/*----------------------------------------------------------------------------- + * FixColourMapEntries - when the pixel format uses a "colour map", fix + * read-only colour map entries. + * + * ***************** NOT CURRENTLY SUPPORTED ***************** + */ + +typedef struct { + CARD8 type; /* always rfbFixColourMapEntries */ + CARD8 pad; + CARD16 firstColour; + CARD16 nColours; + + /* Followed by nColours * 3 * CARD16 + r1, g1, b1, r2, g2, b2, r3, g3, b3, ..., rn, bn, gn */ + +} rfbFixColourMapEntriesMsg; + +#define sz_rfbFixColourMapEntriesMsg 6 + + +/*----------------------------------------------------------------------------- + * SetEncodings - tell the RFB server which encoding types we accept. Put them + * in order of preference, if we have any. We may always receive raw + * encoding, even if we don't specify it here. + */ + +typedef struct { + CARD8 type; /* always rfbSetEncodings */ + CARD8 pad; + CARD16 nEncodings; + /* followed by nEncodings * CARD32 encoding types */ +} rfbSetEncodingsMsg; + +#define sz_rfbSetEncodingsMsg 4 + + +/*----------------------------------------------------------------------------- + * FramebufferUpdateRequest - request for a framebuffer update. If incremental + * is true then the client just wants the changes since the last update. If + * false then it wants the whole of the specified rectangle. + */ + +typedef struct { + CARD8 type; /* always rfbFramebufferUpdateRequest */ + CARD8 incremental; + CARD16 x; + CARD16 y; + CARD16 w; + CARD16 h; +} rfbFramebufferUpdateRequestMsg; + +#define sz_rfbFramebufferUpdateRequestMsg 10 + + +/*----------------------------------------------------------------------------- + * KeyEvent - key press or release + * + * Keys are specified using the "keysym" values defined by the X Window System. + * For most ordinary keys, the keysym is the same as the corresponding ASCII + * value. Other common keys are: + * + * BackSpace 0xff08 + * Tab 0xff09 + * Return or Enter 0xff0d + * Escape 0xff1b + * Insert 0xff63 + * Delete 0xffff + * Home 0xff50 + * End 0xff57 + * Page Up 0xff55 + * Page Down 0xff56 + * Left 0xff51 + * Up 0xff52 + * Right 0xff53 + * Down 0xff54 + * F1 0xffbe + * F2 0xffbf + * ... ... + * F12 0xffc9 + * Shift 0xffe1 + * Control 0xffe3 + * Meta 0xffe7 + * Alt 0xffe9 + */ + +typedef struct { + CARD8 type; /* always rfbKeyEvent */ + CARD8 down; /* true if down (press), false if up */ + CARD16 pad; + CARD32 key; /* key is specified as an X keysym */ +} rfbKeyEventMsg; + +#define sz_rfbKeyEventMsg 8 + + +/*----------------------------------------------------------------------------- + * PointerEvent - mouse/pen move and/or button press. + */ + +typedef struct { + CARD8 type; /* always rfbPointerEvent */ + CARD8 buttonMask; /* bits 0-7 are buttons 1-8, 0=up, 1=down */ + CARD16 x; + CARD16 y; +} rfbPointerEventMsg; + +#define rfbButton1Mask 1 +#define rfbButton2Mask 2 +#define rfbButton3Mask 4 + +#define sz_rfbPointerEventMsg 6 + + + +/*----------------------------------------------------------------------------- + * ClientCutText - the client has new text in its cut buffer. + */ + +typedef struct { + CARD8 type; /* always rfbClientCutText */ + CARD8 pad1; + CARD16 pad2; + CARD32 length; + /* followed by char text[length] */ +} rfbClientCutTextMsg; + +#define sz_rfbClientCutTextMsg 8 + + + +/*----------------------------------------------------------------------------- + * Union of all client->server messages. + */ + +typedef union { + CARD8 type; + rfbSetPixelFormatMsg spf; + rfbFixColourMapEntriesMsg fcme; + rfbSetEncodingsMsg se; + rfbFramebufferUpdateRequestMsg fur; + rfbKeyEventMsg ke; + rfbPointerEventMsg pe; + rfbClientCutTextMsg cct; +} rfbClientToServerMsg; diff --git a/rfbserver.c b/rfbserver.c new file mode 100644 index 0000000..3a185b4 --- /dev/null +++ b/rfbserver.c @@ -0,0 +1,1443 @@ +/* + * rfbserver.c - deal with server-side of the RFB protocol. + */ + +/* + * OSXvnc Copyright (C) 2001 Dan McGuirk . + * Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge. + * All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_PTHREADS +#include +#endif +#include "rfb.h" + +rfbClientPtr pointerClient = NULL; /* Mutex for pointer events */ + +static void rfbProcessClientProtocolVersion(rfbClientPtr cl); +static void rfbProcessClientNormalMessage(rfbClientPtr cl); +static void rfbProcessClientInitMessage(rfbClientPtr cl); + + +struct rfbClientIterator { + rfbClientPtr next; +}; + +#ifdef HAVE_PTHREADS +static pthread_mutex_t rfbClientListMutex; +#endif +static struct rfbClientIterator rfbClientIteratorInstance; + +void +rfbClientListInit(rfbScreenInfoPtr rfbScreen) +{ + rfbScreen->rfbClientHead = NULL; +#ifdef HAVE_PTHREADS + pthread_mutex_init(&rfbClientListMutex, NULL); +#endif +} + +rfbClientIteratorPtr +rfbGetClientIterator(rfbScreenInfoPtr rfbScreen) +{ +#ifdef HAVE_PTHREADS + pthread_mutex_lock(&rfbClientListMutex); +#endif + rfbClientIteratorInstance.next = rfbScreen->rfbClientHead; + + return &rfbClientIteratorInstance; +} + +rfbClientPtr +rfbClientIteratorNext(rfbClientIteratorPtr iterator) +{ + rfbClientPtr result; + result = iterator->next; + if (result) + iterator->next = result->next; + return result; +} + +void +rfbReleaseClientIterator(rfbClientIteratorPtr iterator) +{ +#ifdef HAVE_PTHREADS + pthread_mutex_unlock(&rfbClientListMutex); +#endif +} + + +/* + * rfbNewClientConnection is called from sockets.c when a new connection + * comes in. + */ + +void +rfbNewClientConnection(rfbScreen,sock) + rfbScreenInfoPtr rfbScreen; + int sock; +{ + rfbClientPtr cl; + + cl = rfbNewClient(rfbScreen,sock); +} + + +/* + * rfbReverseConnection is called by the CORBA stuff to make an outward + * connection to a "listening" RFB client. + */ + +rfbClientPtr +rfbReverseConnection(host, port) + char *host; + int port; +{ + return NULL; + +#ifdef NOT_YET + int sock; + rfbClientPtr cl; + + if ((sock = rfbConnect(host, port)) < 0) + return (rfbClientPtr)NULL; + + cl = rfbNewClient(sock); + + if (cl) { + cl->reverseConnection = TRUE; + } + + return cl; +#endif +} + + +/* + * rfbNewClient is called when a new connection has been made by whatever + * means. + */ + +rfbClientPtr +rfbNewClient(rfbScreen,sock) + rfbScreenInfoPtr rfbScreen; + int sock; +{ + rfbProtocolVersionMsg pv; + rfbClientIteratorPtr iterator; + rfbClientPtr cl; + BoxRec box; + struct sockaddr_in addr; + int addrlen = sizeof(struct sockaddr_in); + int i; + + rfbLog(" other clients:\n"); + iterator = rfbGetClientIterator(rfbScreen); + while ((cl = rfbClientIteratorNext(iterator)) != NULL) { + rfbLog(" %s\n",cl->host); + } + rfbReleaseClientIterator(iterator); + + cl = (rfbClientPtr)xalloc(sizeof(rfbClientRec)); + + cl->screen = rfbScreen; + cl->sock = sock; + getpeername(sock, (struct sockaddr *)&addr, &addrlen); + cl->host = strdup(inet_ntoa(addr.sin_addr)); + +#ifdef HAVE_PTHREADS + pthread_mutex_init(&cl->outputMutex, NULL); +#endif + + cl->state = RFB_PROTOCOL_VERSION; + + cl->reverseConnection = FALSE; + cl->readyForSetColourMapEntries = FALSE; + cl->useCopyRect = FALSE; + cl->preferredEncoding = rfbEncodingRaw; + cl->correMaxWidth = 48; + cl->correMaxHeight = 48; + + REGION_INIT(rfbScreen,&cl->copyRegion,NullBox,0); + cl->copyDX = 0; + cl->copyDY = 0; + + box.x1 = box.y1 = 0; + box.x2 = rfbScreen->width; + box.y2 = rfbScreen->height; + REGION_INIT(pScreen,&cl->modifiedRegion,&box,0); + +#ifdef HAVE_PTHREADS + pthread_mutex_init(&cl->updateMutex, NULL); + pthread_cond_init(&cl->updateCond, NULL); +#endif + + REGION_INIT(pScreen,&cl->requestedRegion,NullBox,0); + + cl->format = cl->screen->rfbServerFormat; + cl->translateFn = rfbTranslateNone; + cl->translateLookupTable = NULL; + +#ifdef HAVE_PTHREADS + pthread_mutex_lock(&rfbClientListMutex); +#endif + cl->next = rfbScreen->rfbClientHead; + cl->prev = NULL; + if (rfbScreen->rfbClientHead) + rfbScreen->rfbClientHead->prev = cl; + + rfbScreen->rfbClientHead = cl; +#ifdef HAVE_PTHREADS + pthread_mutex_unlock(&rfbClientListMutex); +#endif + + cl->tightCompressLevel = TIGHT_DEFAULT_COMPRESSION; + cl->tightQualityLevel = -1; + for (i = 0; i < 4; i++) + cl->zsActive[i] = FALSE; + + cl->enableCursorShapeUpdates = FALSE; + cl->enableLastRectEncoding = FALSE; + + rfbResetStats(cl); + + cl->compStreamInited = FALSE; + cl->compStream.total_in = 0; + cl->compStream.total_out = 0; + cl->compStream.zalloc = Z_NULL; + cl->compStream.zfree = Z_NULL; + cl->compStream.opaque = Z_NULL; + + cl->zlibCompressLevel = 5; + + sprintf(pv,rfbProtocolVersionFormat,rfbProtocolMajorVersion, + rfbProtocolMinorVersion); + + if (WriteExact(cl, pv, sz_rfbProtocolVersionMsg) < 0) { + rfbLogPerror("rfbNewClient: write"); + rfbCloseClient(cl); + return NULL; + } + + return cl; +} + + +/* + * rfbClientConnectionGone is called from sockets.c just after a connection + * has gone away. + */ + +void +rfbClientConnectionGone(cl) + rfbClientPtr cl; +{ + int i; +#ifdef HAVE_PTHREADS + pthread_mutex_lock(&rfbClientListMutex); +#endif + + rfbLog("Client %s gone\n",cl->host); + free(cl->host); + + /* Release the compression state structures if any. */ + if ( cl->compStreamInited == TRUE ) { + deflateEnd( &(cl->compStream) ); + } + + for (i = 0; i < 4; i++) { + if (cl->zsActive[i]) + deflateEnd(&cl->zsStruct[i]); + } + + if (pointerClient == cl) + pointerClient = NULL; + + if (cl->prev) + cl->prev->next = cl->next; + else + cl->screen->rfbClientHead = cl->next; + if (cl->next) + cl->next->prev = cl->prev; + +#ifdef HAVE_PTHREADS + pthread_mutex_unlock(&rfbClientListMutex); +#endif + + REGION_UNINIT(pScreen,&cl->modifiedRegion); + + rfbPrintStats(cl); + + if (cl->translateLookupTable) free(cl->translateLookupTable); + +#ifdef HAVE_PTHREADS + pthread_cond_destroy(&cl->updateCond); + pthread_mutex_destroy(&cl->updateMutex); + pthread_mutex_destroy(&cl->outputMutex); +#endif + + xfree(cl); +} + + +/* + * rfbProcessClientMessage is called when there is data to read from a client. + */ + +void +rfbProcessClientMessage(cl) + rfbClientPtr cl; +{ + switch (cl->state) { + case RFB_PROTOCOL_VERSION: + rfbProcessClientProtocolVersion(cl); + return; + case RFB_AUTHENTICATION: + rfbAuthProcessClientMessage(cl); + return; + case RFB_INITIALISATION: + rfbProcessClientInitMessage(cl); + return; + default: + rfbProcessClientNormalMessage(cl); + return; + } +} + + +/* + * rfbProcessClientProtocolVersion is called when the client sends its + * protocol version. + */ + +static void +rfbProcessClientProtocolVersion(cl) + rfbClientPtr cl; +{ + rfbProtocolVersionMsg pv; + int n, major, minor; + char failureReason[256]; + + if ((n = ReadExact(cl, pv, sz_rfbProtocolVersionMsg)) <= 0) { + if (n == 0) + rfbLog("rfbProcessClientProtocolVersion: client gone\n"); + else + rfbLogPerror("rfbProcessClientProtocolVersion: read"); + rfbCloseClient(cl); + return; + } + + pv[sz_rfbProtocolVersionMsg] = 0; + if (sscanf(pv,rfbProtocolVersionFormat,&major,&minor) != 2) { + rfbLog("rfbProcessClientProtocolVersion: not a valid RFB client\n"); + rfbCloseClient(cl); + return; + } + rfbLog("Protocol version %d.%d\n", major, minor); + + if (major != rfbProtocolMajorVersion) { + /* Major version mismatch - send a ConnFailed message */ + + rfbLog("Major version mismatch\n"); + sprintf(failureReason, + "RFB protocol version mismatch - server %d.%d, client %d.%d", + rfbProtocolMajorVersion,rfbProtocolMinorVersion,major,minor); + rfbClientConnFailed(cl, failureReason); + return; + } + + if (minor != rfbProtocolMinorVersion) { + /* Minor version mismatch - warn but try to continue */ + rfbLog("Ignoring minor version mismatch\n"); + } + + rfbAuthNewClient(cl); +} + + +/* + * rfbClientConnFailed is called when a client connection has failed either + * because it talks the wrong protocol or it has failed authentication. + */ + +void +rfbClientConnFailed(cl, reason) + rfbClientPtr cl; + char *reason; +{ + char *buf; + int len = strlen(reason); + + buf = (char *)xalloc(8 + len); + ((CARD32 *)buf)[0] = Swap32IfLE(rfbConnFailed); + ((CARD32 *)buf)[1] = Swap32IfLE(len); + memcpy(buf + 8, reason, len); + + if (WriteExact(cl, buf, 8 + len) < 0) + rfbLogPerror("rfbClientConnFailed: write"); + xfree(buf); + rfbCloseClient(cl); +} + + +/* + * rfbProcessClientInitMessage is called when the client sends its + * initialisation message. + */ + +static void +rfbProcessClientInitMessage(cl) + rfbClientPtr cl; +{ + rfbClientInitMsg ci; + char buf[256]; + rfbServerInitMsg *si = (rfbServerInitMsg *)buf; + int len, n; + rfbClientIteratorPtr iterator; + rfbClientPtr otherCl; + + if ((n = ReadExact(cl, (char *)&ci,sz_rfbClientInitMsg)) <= 0) { + if (n == 0) + rfbLog("rfbProcessClientInitMessage: client gone\n"); + else + rfbLogPerror("rfbProcessClientInitMessage: read"); + rfbCloseClient(cl); + return; + } + + si->framebufferWidth = Swap16IfLE(cl->screen->width); + si->framebufferHeight = Swap16IfLE(cl->screen->height); + si->format = cl->screen->rfbServerFormat; + si->format.redMax = Swap16IfLE(si->format.redMax); + si->format.greenMax = Swap16IfLE(si->format.greenMax); + si->format.blueMax = Swap16IfLE(si->format.blueMax); + + if (strlen(cl->screen->desktopName) > 128) /* sanity check on desktop name len */ + cl->screen->desktopName[128] = 0; + + strcpy(buf + sz_rfbServerInitMsg, cl->screen->desktopName); + len = strlen(buf + sz_rfbServerInitMsg); + si->nameLength = Swap32IfLE(len); + + if (WriteExact(cl, buf, sz_rfbServerInitMsg + len) < 0) { + rfbLogPerror("rfbProcessClientInitMessage: write"); + rfbCloseClient(cl); + return; + } + + cl->state = RFB_NORMAL; + + if (!cl->reverseConnection && + (cl->screen->rfbNeverShared || (!cl->screen->rfbAlwaysShared && !ci.shared))) { + + if (cl->screen->rfbDontDisconnect) { + iterator = rfbGetClientIterator(cl->screen); + while ((otherCl = rfbClientIteratorNext(iterator)) != NULL) { + if ((otherCl != cl) && (otherCl->state == RFB_NORMAL)) { + rfbLog("-dontdisconnect: Not shared & existing client\n"); + rfbLog(" refusing new client %s\n", cl->host); + rfbCloseClient(cl); + rfbReleaseClientIterator(iterator); + return; + } + } + rfbReleaseClientIterator(iterator); + } else { + iterator = rfbGetClientIterator(cl->screen); + while ((otherCl = rfbClientIteratorNext(iterator)) != NULL) { + if ((otherCl != cl) && (otherCl->state == RFB_NORMAL)) { + rfbLog("Not shared - closing connection to client %s\n", + otherCl->host); + rfbCloseClient(otherCl); + } + } + rfbReleaseClientIterator(iterator); + } + } +} + + +/* + * rfbProcessClientNormalMessage is called when the client has sent a normal + * protocol message. + */ + +static void +rfbProcessClientNormalMessage(cl) + rfbClientPtr cl; +{ + int n=0; + rfbClientToServerMsg msg; + char *str; + + if ((n = ReadExact(cl, (char *)&msg, 1)) <= 0) { + if (n != 0) + rfbLogPerror("rfbProcessClientNormalMessage: read"); + rfbCloseClient(cl); + return; + } + + switch (msg.type) { + + case rfbSetPixelFormat: + + if ((n = ReadExact(cl, ((char *)&msg) + 1, + sz_rfbSetPixelFormatMsg - 1)) <= 0) { + if (n != 0) + rfbLogPerror("rfbProcessClientNormalMessage: read"); + rfbCloseClient(cl); + return; + } + + cl->format.bitsPerPixel = msg.spf.format.bitsPerPixel; + cl->format.depth = msg.spf.format.depth; + cl->format.bigEndian = (msg.spf.format.bigEndian ? 1 : 0); + cl->format.trueColour = (msg.spf.format.trueColour ? 1 : 0); + cl->format.redMax = Swap16IfLE(msg.spf.format.redMax); + cl->format.greenMax = Swap16IfLE(msg.spf.format.greenMax); + cl->format.blueMax = Swap16IfLE(msg.spf.format.blueMax); + cl->format.redShift = msg.spf.format.redShift; + cl->format.greenShift = msg.spf.format.greenShift; + cl->format.blueShift = msg.spf.format.blueShift; + + cl->readyForSetColourMapEntries = TRUE; + + rfbSetTranslateFunction(cl); + return; + + + case rfbFixColourMapEntries: + if ((n = ReadExact(cl, ((char *)&msg) + 1, + sz_rfbFixColourMapEntriesMsg - 1)) <= 0) { + if (n != 0) + rfbLogPerror("rfbProcessClientNormalMessage: read"); + rfbCloseClient(cl); + return; + } + rfbLog("rfbProcessClientNormalMessage: %s", + "FixColourMapEntries unsupported\n"); + rfbCloseClient(cl); + return; + + + case rfbSetEncodings: + { + int i; + CARD32 enc; + + if ((n = ReadExact(cl, ((char *)&msg) + 1, + sz_rfbSetEncodingsMsg - 1)) <= 0) { + if (n != 0) + rfbLogPerror("rfbProcessClientNormalMessage: read"); + rfbCloseClient(cl); + return; + } + + msg.se.nEncodings = Swap16IfLE(msg.se.nEncodings); + + cl->preferredEncoding = -1; + cl->useCopyRect = FALSE; + cl->enableCursorShapeUpdates = FALSE; + cl->enableLastRectEncoding = FALSE; + + for (i = 0; i < msg.se.nEncodings; i++) { + if ((n = ReadExact(cl, (char *)&enc, 4)) <= 0) { + if (n != 0) + rfbLogPerror("rfbProcessClientNormalMessage: read"); + rfbCloseClient(cl); + return; + } + enc = Swap32IfLE(enc); + + switch (enc) { + + case rfbEncodingCopyRect: + cl->useCopyRect = TRUE; + break; + case rfbEncodingRaw: + if (cl->preferredEncoding == -1) { + cl->preferredEncoding = enc; + rfbLog("Using raw encoding for client %s\n", + cl->host); + } + break; + case rfbEncodingRRE: + if (cl->preferredEncoding == -1) { + cl->preferredEncoding = enc; + rfbLog("Using rre encoding for client %s\n", + cl->host); + } + break; + case rfbEncodingCoRRE: + if (cl->preferredEncoding == -1) { + cl->preferredEncoding = enc; + rfbLog("Using CoRRE encoding for client %s\n", + cl->host); + } + break; + case rfbEncodingHextile: + if (cl->preferredEncoding == -1) { + cl->preferredEncoding = enc; + rfbLog("Using hextile encoding for client %s\n", + cl->host); + } + break; + case rfbEncodingZlib: + if (cl->preferredEncoding == -1) { + cl->preferredEncoding = enc; + rfbLog("Using zlib encoding for client %s\n", + cl->host); + } + break; + case rfbEncodingTight: + if (cl->preferredEncoding == -1) { + cl->preferredEncoding = enc; + rfbLog("Using tight encoding for client %s\n", + cl->host); + } + break; + case rfbEncodingXCursor: + rfbLog("Enabling X-style cursor updates for client %s\n", + cl->host); + cl->enableCursorShapeUpdates = TRUE; + cl->useRichCursorEncoding = FALSE; + cl->cursorWasChanged = TRUE; + break; + case rfbEncodingRichCursor: + if (!cl->enableCursorShapeUpdates) { + rfbLog("Enabling full-color cursor updates for client " + "%s\n", cl->host); + cl->enableCursorShapeUpdates = TRUE; + cl->useRichCursorEncoding = TRUE; + cl->cursorWasChanged = TRUE; + } + break; + case rfbEncodingLastRect: + if (!cl->enableLastRectEncoding) { + rfbLog("Enabling LastRect protocol extension for client " + "%s\n", cl->host); + cl->enableLastRectEncoding = TRUE; + } + break; + default: + if ( enc >= (CARD32)rfbEncodingCompressLevel0 && + enc <= (CARD32)rfbEncodingCompressLevel9 ) { + cl->zlibCompressLevel = enc & 0x0F; + cl->tightCompressLevel = enc & 0x0F; + rfbLog("Using compression level %d for client %s\n", + cl->tightCompressLevel, cl->host); + } else if ( enc >= (CARD32)rfbEncodingQualityLevel0 && + enc <= (CARD32)rfbEncodingQualityLevel9 ) { + cl->tightQualityLevel = enc & 0x0F; + rfbLog("Using image quality level %d for client %s\n", + cl->tightQualityLevel, cl->host); + } else + rfbLog("rfbProcessClientNormalMessage: ignoring unknown " + "encoding type %d\n", (int)enc); + } + } + + if (cl->preferredEncoding == -1) { + cl->preferredEncoding = rfbEncodingRaw; + } + + return; + } + + + case rfbFramebufferUpdateRequest: + { + RegionRec tmpRegion; + BoxRec box; + + if ((n = ReadExact(cl, ((char *)&msg) + 1, + sz_rfbFramebufferUpdateRequestMsg-1)) <= 0) { + if (n != 0) + rfbLogPerror("rfbProcessClientNormalMessage: read"); + rfbCloseClient(cl); + return; + } + + box.x1 = Swap16IfLE(msg.fur.x); + box.y1 = Swap16IfLE(msg.fur.y); + box.x2 = box.x1 + Swap16IfLE(msg.fur.w); + box.y2 = box.y1 + Swap16IfLE(msg.fur.h); + SAFE_REGION_INIT(pScreen,&tmpRegion,&box,0); + +#ifdef HAVE_PTHREADS + pthread_mutex_lock(&cl->updateMutex); +#endif + REGION_UNION(pScreen, &cl->requestedRegion, &cl->requestedRegion, + &tmpRegion); + +#ifdef NOT_YET + if (!cl->readyForSetColourMapEntries) { + /* client hasn't sent a SetPixelFormat so is using server's */ + cl->readyForSetColourMapEntries = TRUE; + if (!cl->format.trueColour) { + if (!rfbSetClientColourMap(cl, 0, 0)) { + REGION_UNINIT(pScreen,&tmpRegion); + return; + } + } + } +#endif + + if (!msg.fur.incremental) { + REGION_UNION(pScreen,&cl->modifiedRegion,&cl->modifiedRegion, + &tmpRegion); + REGION_SUBTRACT(pScreen,&cl->copyRegion,&cl->copyRegion,&tmpRegion); + } +#ifdef HAVE_PTHREADS + pthread_cond_signal(&cl->updateCond); + pthread_mutex_unlock(&cl->updateMutex); +#endif + + if(cl->sock>=0 && FB_UPDATE_PENDING(cl)) { + rfbSendFramebufferUpdate(cl,cl->modifiedRegion); + } + + REGION_UNINIT(pScreen,&tmpRegion); + + return; + } + + case rfbKeyEvent: + + cl->rfbKeyEventsRcvd++; + + if ((n = ReadExact(cl, ((char *)&msg) + 1, + sz_rfbKeyEventMsg - 1)) <= 0) { + if (n != 0) + rfbLogPerror("rfbProcessClientNormalMessage: read"); + rfbCloseClient(cl); + return; + } + + cl->screen->kbdAddEvent(msg.ke.down, (KeySym)Swap32IfLE(msg.ke.key), cl); + return; + + + case rfbPointerEvent: + + cl->rfbPointerEventsRcvd++; + + if ((n = ReadExact(cl, ((char *)&msg) + 1, + sz_rfbPointerEventMsg - 1)) <= 0) { + if (n != 0) + rfbLogPerror("rfbProcessClientNormalMessage: read"); + rfbCloseClient(cl); + return; + } + + if (pointerClient && (pointerClient != cl)) + return; + + if (msg.pe.buttonMask == 0) + pointerClient = NULL; + else + pointerClient = cl; + + cl->screen->ptrAddEvent(msg.pe.buttonMask, + Swap16IfLE(msg.pe.x), Swap16IfLE(msg.pe.y), cl); + return; + + + case rfbClientCutText: + + if ((n = ReadExact(cl, ((char *)&msg) + 1, + sz_rfbClientCutTextMsg - 1)) <= 0) { + if (n != 0) + rfbLogPerror("rfbProcessClientNormalMessage: read"); + rfbCloseClient(cl); + return; + } + + msg.cct.length = Swap32IfLE(msg.cct.length); + + str = (char *)xalloc(msg.cct.length); + + if ((n = ReadExact(cl, str, msg.cct.length)) <= 0) { + if (n != 0) + rfbLogPerror("rfbProcessClientNormalMessage: read"); + xfree(str); + rfbCloseClient(cl); + return; + } + + cl->screen->setXCutText(str, msg.cct.length, cl); + + xfree(str); + return; + + + default: + + rfbLog("rfbProcessClientNormalMessage: unknown message type %d\n", + msg.type); + rfbLog(" ... closing connection\n"); + rfbCloseClient(cl); + return; + } +} + + + +/* + * rfbSendFramebufferUpdate - send the currently pending framebuffer update to + * the RFB client. + */ + +Bool +rfbSendFramebufferUpdate(cl, updateRegion) + rfbClientPtr cl; + RegionRec updateRegion; +{ + int i; + int nUpdateRegionRects; + rfbFramebufferUpdateMsg *fu = (rfbFramebufferUpdateMsg *)cl->updateBuf; + RegionRec updateCopyRegion; + int dx, dy; + Bool sendCursorShape = FALSE; + + /* + * If this client understands cursor shape updates, cursor should be + * removed from the framebuffer. Otherwise, make sure it's put up. + */ + +#ifdef NOT_YET + if (cl->enableCursorShapeUpdates) { + if (cl->screen->cursorIsDrawn) + rfbSpriteRemoveCursor(pScreen); + if (!cl->screen->cursorIsDrawn && cl->cursorWasChanged) + sendCursorShape = TRUE; + } else { + if (!cl->screen->cursorIsDrawn) + rfbSpriteRestoreCursor(pScreen); + } +#endif + + /* + * The modifiedRegion may overlap the destination copyRegion. We remove + * any overlapping bits from the copyRegion (since they'd only be + * overwritten anyway). + */ + + REGION_SUBTRACT(pScreen, &cl->copyRegion, &cl->copyRegion, + &cl->modifiedRegion); + + /* + * The client is interested in the region requestedRegion. The region + * which should be updated now is the intersection of requestedRegion + * and the union of modifiedRegion and copyRegion. If it's empty then + * no update is needed. + */ + + //REGION_INIT(pScreen,&updateRegion,NullBox,0); + //REGION_UNION(pScreen, &updateRegion, &cl->copyRegion, + // &cl->modifiedRegion); + REGION_INTERSECT(pScreen, &updateRegion, &cl->requestedRegion, + &updateRegion); + + if (!REGION_NOTEMPTY(pScreen,&updateRegion) && !sendCursorShape) { + REGION_UNINIT(pScreen,&updateRegion); + return TRUE; + } + + /* + * We assume that the client doesn't have any pixel data outside the + * requestedRegion. In other words, both the source and destination of a + * copy must lie within requestedRegion. So the region we can send as a + * copy is the intersection of the copyRegion with both the requestedRegion + * and the requestedRegion translated by the amount of the copy. We set + * updateCopyRegion to this. + */ + + REGION_INIT(pScreen,&updateCopyRegion,NullBox,0); + REGION_INTERSECT(pScreen, &updateCopyRegion, &cl->copyRegion, + &cl->requestedRegion); + REGION_TRANSLATE(pScreen, &cl->requestedRegion, cl->copyDX, cl->copyDY); + REGION_INTERSECT(pScreen, &updateCopyRegion, &updateCopyRegion, + &cl->requestedRegion); + dx = cl->copyDX; + dy = cl->copyDY; + + /* + * Next we remove updateCopyRegion from updateRegion so that updateRegion + * is the part of this update which is sent as ordinary pixel data (i.e not + * a copy). + */ + + REGION_SUBTRACT(pScreen, &updateRegion, &updateRegion, &updateCopyRegion); + + /* + * Finally we leave modifiedRegion to be the remainder (if any) of parts of + * the screen which are modified but outside the requestedRegion. We also + * empty both the requestedRegion and the copyRegion - note that we never + * carry over a copyRegion for a future update. + */ + + + REGION_UNION(pScreen, &cl->modifiedRegion, &cl->modifiedRegion, + &cl->copyRegion); + REGION_SUBTRACT(pScreen, &cl->modifiedRegion, &cl->modifiedRegion, + &updateRegion); + REGION_SUBTRACT(pScreen, &cl->modifiedRegion, &cl->modifiedRegion, + &updateCopyRegion); + + REGION_EMPTY(pScreen, &cl->requestedRegion); + REGION_EMPTY(pScreen, &cl->copyRegion); + cl->copyDX = 0; + cl->copyDY = 0; + + + /* + * Now send the update. + */ + + cl->rfbFramebufferUpdateMessagesSent++; + + if (cl->preferredEncoding == rfbEncodingCoRRE) { + nUpdateRegionRects = 0; + + for (i = 0; i < REGION_NUM_RECTS(&updateRegion); i++) { + int x = REGION_RECTS(&updateRegion)[i].x1; + int y = REGION_RECTS(&updateRegion)[i].y1; + int w = REGION_RECTS(&updateRegion)[i].x2 - x; + int h = REGION_RECTS(&updateRegion)[i].y2 - y; + nUpdateRegionRects += (((w-1) / cl->correMaxWidth + 1) + * ((h-1) / cl->correMaxHeight + 1)); + } + } else if (cl->preferredEncoding == rfbEncodingZlib) { + nUpdateRegionRects = 0; + + for (i = 0; i < REGION_NUM_RECTS(&updateRegion); i++) { + int x = REGION_RECTS(&updateRegion)[i].x1; + int y = REGION_RECTS(&updateRegion)[i].y1; + int w = REGION_RECTS(&updateRegion)[i].x2 - x; + int h = REGION_RECTS(&updateRegion)[i].y2 - y; + nUpdateRegionRects += (((h-1) / (ZLIB_MAX_SIZE( w ) / w)) + 1); + } + } else if (cl->preferredEncoding == rfbEncodingTight) { + nUpdateRegionRects = 0; + + for (i = 0; i < REGION_NUM_RECTS(&updateRegion); i++) { + int x = REGION_RECTS(&updateRegion)[i].x1; + int y = REGION_RECTS(&updateRegion)[i].y1; + int w = REGION_RECTS(&updateRegion)[i].x2 - x; + int h = REGION_RECTS(&updateRegion)[i].y2 - y; + int n = rfbNumCodedRectsTight(cl, x, y, w, h); + if (n == 0) { + nUpdateRegionRects = 0xFFFF; + break; + } + nUpdateRegionRects += n; + } + } else { + nUpdateRegionRects = REGION_NUM_RECTS(&updateRegion); + } + + fu->type = rfbFramebufferUpdate; + if (nUpdateRegionRects != 0xFFFF) { + fu->nRects = Swap16IfLE(REGION_NUM_RECTS(&updateCopyRegion) + + nUpdateRegionRects + !!sendCursorShape); + } else { + fu->nRects = 0xFFFF; + } + cl->ublen = sz_rfbFramebufferUpdateMsg; + +#ifdef NOT_YET + if (sendCursorShape) { + cl->cursorWasChanged = FALSE; + if (!rfbSendCursorShape(cl, pScreen)) + return FALSE; + } +#endif + + if (REGION_NOTEMPTY(pScreen,&updateCopyRegion)) { + if (!rfbSendCopyRegion(cl,&updateCopyRegion,dx,dy)) { + REGION_UNINIT(pScreen,&updateRegion); + REGION_UNINIT(pScreen,&updateCopyRegion); + return FALSE; + } + } + + REGION_UNINIT(pScreen,&updateCopyRegion); + + for (i = 0; i < REGION_NUM_RECTS(&updateRegion); i++) { + int x = REGION_RECTS(&updateRegion)[i].x1; + int y = REGION_RECTS(&updateRegion)[i].y1; + int w = REGION_RECTS(&updateRegion)[i].x2 - x; + int h = REGION_RECTS(&updateRegion)[i].y2 - y; + + cl->rfbRawBytesEquivalent += (sz_rfbFramebufferUpdateRectHeader + + w * (cl->format.bitsPerPixel / 8) * h); + + switch (cl->preferredEncoding) { + case rfbEncodingRaw: + if (!rfbSendRectEncodingRaw(cl, x, y, w, h)) { + return FALSE; + } + break; + case rfbEncodingRRE: + if (!rfbSendRectEncodingRRE(cl, x, y, w, h)) { + return FALSE; + } + break; + case rfbEncodingCoRRE: + if (!rfbSendRectEncodingCoRRE(cl, x, y, w, h)) { + return FALSE; + } + break; + case rfbEncodingHextile: + if (!rfbSendRectEncodingHextile(cl, x, y, w, h)) { + return FALSE; + } + break; + case rfbEncodingZlib: + if (!rfbSendRectEncodingZlib(cl, x, y, w, h)) { + REGION_UNINIT(pScreen,&updateRegion); + return FALSE; + } + break; + case rfbEncodingTight: + if (!rfbSendRectEncodingTight(cl, x, y, w, h)) { + REGION_UNINIT(pScreen,&updateRegion); + return FALSE; + } + break; + } + } + + if ( nUpdateRegionRects == 0xFFFF && + !rfbSendLastRectMarker(cl) ) { + return FALSE; + } + + if (!rfbSendUpdateBuf(cl)) + return FALSE; + + return TRUE; +} + + +/* + * Send the copy region as a string of CopyRect encoded rectangles. + * The only slightly tricky thing is that we should send the messages in + * the correct order so that an earlier CopyRect will not corrupt the source + * of a later one. + */ + +static Bool +rfbSendCopyRegion(cl, reg, dx, dy) + rfbClientPtr cl; + RegionPtr reg; + int dx, dy; +{ + int nrects, nrectsInBand, x_inc, y_inc, thisRect, firstInNextBand; + int x, y, w, h; + rfbFramebufferUpdateRectHeader rect; + rfbCopyRect cr; + + nrects = REGION_NUM_RECTS(reg); + + if (dx <= 0) { + x_inc = 1; + } else { + x_inc = -1; + } + + if (dy <= 0) { + thisRect = 0; + y_inc = 1; + } else { + thisRect = nrects - 1; + y_inc = -1; + } + + while (nrects > 0) { + + firstInNextBand = thisRect; + nrectsInBand = 0; + + while ((nrects > 0) && + (REGION_RECTS(reg)[firstInNextBand].y1 + == REGION_RECTS(reg)[thisRect].y1)) + { + firstInNextBand += y_inc; + nrects--; + nrectsInBand++; + } + + if (x_inc != y_inc) { + thisRect = firstInNextBand - y_inc; + } + + while (nrectsInBand > 0) { + if ((cl->ublen + sz_rfbFramebufferUpdateRectHeader + + sz_rfbCopyRect) > UPDATE_BUF_SIZE) + { + if (!rfbSendUpdateBuf(cl)) + return FALSE; + } + + x = REGION_RECTS(reg)[thisRect].x1; + y = REGION_RECTS(reg)[thisRect].y1; + w = REGION_RECTS(reg)[thisRect].x2 - x; + h = REGION_RECTS(reg)[thisRect].y2 - y; + + rect.r.x = Swap16IfLE(x); + rect.r.y = Swap16IfLE(y); + rect.r.w = Swap16IfLE(w); + rect.r.h = Swap16IfLE(h); + rect.encoding = Swap32IfLE(rfbEncodingCopyRect); + + memcpy(&cl->updateBuf[cl->ublen], (char *)&rect, + sz_rfbFramebufferUpdateRectHeader); + cl->ublen += sz_rfbFramebufferUpdateRectHeader; + + cr.srcX = Swap16IfLE(x - dx); + cr.srcY = Swap16IfLE(y - dy); + + memcpy(&cl->updateBuf[cl->ublen], (char *)&cr, sz_rfbCopyRect); + cl->ublen += sz_rfbCopyRect; + + cl->rfbRectanglesSent[rfbEncodingCopyRect]++; + cl->rfbBytesSent[rfbEncodingCopyRect] + += sz_rfbFramebufferUpdateRectHeader + sz_rfbCopyRect; + + thisRect += x_inc; + nrectsInBand--; + } + + thisRect = firstInNextBand; + } + + return TRUE; +} + +/* + * Send a given rectangle in raw encoding (rfbEncodingRaw). + */ + +Bool +rfbSendRectEncodingRaw(cl, x, y, w, h) + rfbClientPtr cl; + int x, y, w, h; +{ + rfbFramebufferUpdateRectHeader rect; + int nlines; + int bytesPerLine = w * (cl->format.bitsPerPixel / 8); + char *fbptr = (cl->screen->frameBuffer + (cl->screen->paddedWidthInBytes * y) + + (x * (cl->screen->bitsPerPixel / 8))); + + if (cl->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE) { + if (!rfbSendUpdateBuf(cl)) + return FALSE; + } + + rect.r.x = Swap16IfLE(x); + rect.r.y = Swap16IfLE(y); + rect.r.w = Swap16IfLE(w); + rect.r.h = Swap16IfLE(h); + rect.encoding = Swap32IfLE(rfbEncodingRaw); + + memcpy(&cl->updateBuf[cl->ublen], (char *)&rect,sz_rfbFramebufferUpdateRectHeader); + cl->ublen += sz_rfbFramebufferUpdateRectHeader; + + cl->rfbRectanglesSent[rfbEncodingRaw]++; + cl->rfbBytesSent[rfbEncodingRaw] + += sz_rfbFramebufferUpdateRectHeader + bytesPerLine * h; + + nlines = (UPDATE_BUF_SIZE - cl->ublen) / bytesPerLine; + + while (TRUE) { + if (nlines > h) + nlines = h; + + (*cl->translateFn)(cl->translateLookupTable, + &(cl->screen->rfbServerFormat), + &cl->format, fbptr, &cl->updateBuf[cl->ublen], + cl->screen->paddedWidthInBytes, w, nlines); + + cl->ublen += nlines * bytesPerLine; + h -= nlines; + + if (h == 0) /* rect fitted in buffer, do next one */ + return TRUE; + + /* buffer full - flush partial rect and do another nlines */ + + if (!rfbSendUpdateBuf(cl)) + return FALSE; + + fbptr += (cl->screen->paddedWidthInBytes * nlines); + + nlines = (UPDATE_BUF_SIZE - cl->ublen) / bytesPerLine; + if (nlines == 0) { + rfbLog("rfbSendRectEncodingRaw: send buffer too small for %d " + "bytes per line\n", bytesPerLine); + rfbCloseClient(cl); + return FALSE; + } + } +} + + + +/* + * Send an empty rectangle with encoding field set to value of + * rfbEncodingLastRect to notify client that this is the last + * rectangle in framebuffer update ("LastRect" extension of RFB + * protocol). + */ + +static Bool +rfbSendLastRectMarker(cl) + rfbClientPtr cl; +{ + rfbFramebufferUpdateRectHeader rect; + + if (cl->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE) { + if (!rfbSendUpdateBuf(cl)) + return FALSE; + } + + rect.encoding = Swap32IfLE(rfbEncodingLastRect); + rect.r.x = 0; + rect.r.y = 0; + rect.r.w = 0; + rect.r.h = 0; + + memcpy(&cl->updateBuf[cl->ublen], (char *)&rect,sz_rfbFramebufferUpdateRectHeader); + cl->ublen += sz_rfbFramebufferUpdateRectHeader; + + cl->rfbLastRectMarkersSent++; + cl->rfbLastRectBytesSent += sz_rfbFramebufferUpdateRectHeader; + + return TRUE; +} + + +/* + * Send the contents of cl->updateBuf. Returns 1 if successful, -1 if + * not (errno should be set). + */ + +Bool +rfbSendUpdateBuf(cl) + rfbClientPtr cl; +{ + /* + int i; + for (i = 0; i < cl->ublen; i++) { + fprintf(stderr,"%02x ",((unsigned char *)cl->updateBuf)[i]); + } + fprintf(stderr,"\n"); + */ + + if (WriteExact(cl, cl->updateBuf, cl->ublen) < 0) { + rfbLogPerror("rfbSendUpdateBuf: write"); + rfbCloseClient(cl); + return FALSE; + } + + cl->ublen = 0; + return TRUE; +} + +#ifdef NOT_YET +/* + * rfbSendSetColourMapEntries sends a SetColourMapEntries message to the + * client, using values from the currently installed colormap. + */ + +Bool +rfbSendSetColourMapEntries(cl, firstColour, nColours) + rfbClientPtr cl; + int firstColour; + int nColours; +{ + char buf[sz_rfbSetColourMapEntriesMsg + 256 * 3 * 2]; + rfbSetColourMapEntriesMsg *scme = (rfbSetColourMapEntriesMsg *)buf; + CARD16 *rgb = (CARD16 *)(&buf[sz_rfbSetColourMapEntriesMsg]); + EntryPtr pent; + int i, len; + + scme->type = rfbSetColourMapEntries; + + scme->firstColour = Swap16IfLE(firstColour); + scme->nColours = Swap16IfLE(nColours); + + len = sz_rfbSetColourMapEntriesMsg; + + pent = (EntryPtr)&rfbInstalledColormap->red[firstColour]; + for (i = 0; i < nColours; i++) { + if (pent->fShared) { + rgb[i*3] = Swap16IfLE(pent->co.shco.red->color); + rgb[i*3+1] = Swap16IfLE(pent->co.shco.green->color); + rgb[i*3+2] = Swap16IfLE(pent->co.shco.blue->color); + } else { + rgb[i*3] = Swap16IfLE(pent->co.local.red); + rgb[i*3+1] = Swap16IfLE(pent->co.local.green); + rgb[i*3+2] = Swap16IfLE(pent->co.local.blue); + } + pent++; + } + + len += nColours * 3 * 2; + + if (WriteExact(cl->sock, buf, len) < 0) { + rfbLogPerror("rfbSendSetColourMapEntries: write"); + rfbCloseClient(cl); + return FALSE; + } + return TRUE; +} +#endif + +/* + * rfbSendBell sends a Bell message to all the clients. + */ + +void +rfbSendBell(rfbScreenInfoPtr rfbScreen) +{ + rfbClientPtr cl, nextCl; + rfbBellMsg b; + + for (cl = rfbScreen->rfbClientHead; cl; cl = nextCl) { + nextCl = cl->next; + b.type = rfbBell; + if (WriteExact(cl, (char *)&b, sz_rfbBellMsg) < 0) { + rfbLogPerror("rfbSendBell: write"); + rfbCloseClient(cl); + } + } +} + + +/* + * rfbSendServerCutText sends a ServerCutText message to all the clients. + */ + +void +rfbSendServerCutText(rfbScreenInfoPtr rfbScreen,char *str, int len) +{ + rfbClientPtr cl; + rfbServerCutTextMsg sct; + rfbClientIteratorPtr iterator; + + /* XXX bad-- writing with client list lock held */ + iterator = rfbGetClientIterator(rfbScreen); + while ((cl = rfbClientIteratorNext(iterator)) != NULL) { + sct.type = rfbServerCutText; + sct.length = Swap32IfLE(len); + if (WriteExact(cl, (char *)&sct, + sz_rfbServerCutTextMsg) < 0) { + rfbLogPerror("rfbSendServerCutText: write"); + rfbCloseClient(cl); + continue; + } + if (WriteExact(cl, str, len) < 0) { + rfbLogPerror("rfbSendServerCutText: write"); + rfbCloseClient(cl); + } + } + rfbReleaseClientIterator(iterator); +} + +unsigned char ptrAcceleration = 50; + +/***************************************************************************** + * + * UDP can be used for keyboard and pointer events when the underlying + * network is highly reliable. This is really here to support ORL's + * videotile, whose TCP implementation doesn't like sending lots of small + * packets (such as 100s of pen readings per second!). + */ + +void +rfbNewUDPConnection(rfbScreen,sock) + rfbScreenInfoPtr rfbScreen; + int sock; +{ + if (write(sock, &ptrAcceleration, 1) < 0) { + rfbLogPerror("rfbNewUDPConnection: write"); + } +} + +/* + * Because UDP is a message based service, we can't read the first byte and + * then the rest of the packet separately like we do with TCP. We will always + * get a whole packet delivered in one go, so we ask read() for the maximum + * number of bytes we can possibly get. + */ + +#if 0 +void +rfbProcessUDPInput(rfbClientPtr cl) +{ + int n; + rfbClientToServerMsg msg; + + if ((n = read(cl->udpSock, (char *)&msg, sizeof(msg))) <= 0) { + if (n < 0) { + rfbLogPerror("rfbProcessUDPInput: read"); + } + rfbDisconnectUDPSock(cl); + return; + } + + switch (msg.type) { + + case rfbKeyEvent: + if (n != sz_rfbKeyEventMsg) { + rfbLog("rfbProcessUDPInput: key event incorrect length\n"); + rfbDisconnectUDPSock(cl); + return; + } + cl->screen->kbdAddEvent(msg.ke.down, (KeySym)Swap32IfLE(msg.ke.key), cl); + break; + + case rfbPointerEvent: + if (n != sz_rfbPointerEventMsg) { + rfbLog("rfbProcessUDPInput: ptr event incorrect length\n"); + rfbDisconnectUDPSock(cl); + return; + } + cl->screen->ptrAddEvent(msg.pe.buttonMask, + Swap16IfLE(msg.pe.x), Swap16IfLE(msg.pe.y), cl); + break; + + default: + rfbLog("rfbProcessUDPInput: unknown message type %d\n", + msg.type); + rfbDisconnectUDPSock(cl); + } +} +#endif diff --git a/rre.c b/rre.c new file mode 100644 index 0000000..d228642 --- /dev/null +++ b/rre.c @@ -0,0 +1,322 @@ +/* + * rre.c + * + * Routines to implement Rise-and-Run-length Encoding (RRE). This + * code is based on krw's original javatel rfbserver. + */ + +/* + * OSXvnc Copyright (C) 2001 Dan McGuirk . + * Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge. + * All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include +#include "rfb.h" + +/* + * rreBeforeBuf contains pixel data in the client's format. + * rreAfterBuf contains the RRE encoded version. If the RRE encoded version is + * larger than the raw data or if it exceeds rreAfterBufSize then + * raw encoding is used instead. + */ + +static int rreBeforeBufSize = 0; +static char *rreBeforeBuf = NULL; + +static int rreAfterBufSize = 0; +static char *rreAfterBuf = NULL; +static int rreAfterBufLen; + +static int subrectEncode8(CARD8 *data, int w, int h); +static int subrectEncode16(CARD16 *data, int w, int h); +static int subrectEncode32(CARD32 *data, int w, int h); +static CARD32 getBgColour(char *data, int size, int bpp); + + +/* + * rfbSendRectEncodingRRE - send a given rectangle using RRE encoding. + */ + +Bool +rfbSendRectEncodingRRE(cl, x, y, w, h) + rfbClientPtr cl; + int x, y, w, h; +{ + rfbFramebufferUpdateRectHeader rect; + rfbRREHeader hdr; + int nSubrects; + int i; + char *fbptr = (cl->screen->frameBuffer + (cl->screen->paddedWidthInBytes * y) + + (x * (cl->screen->bitsPerPixel / 8))); + + int maxRawSize = (cl->screen->width * cl->screen->height + * (cl->format.bitsPerPixel / 8)); + + if (rreBeforeBufSize < maxRawSize) { + rreBeforeBufSize = maxRawSize; + if (rreBeforeBuf == NULL) + rreBeforeBuf = (char *)xalloc(rreBeforeBufSize); + else + rreBeforeBuf = (char *)xrealloc(rreBeforeBuf, rreBeforeBufSize); + } + + if (rreAfterBufSize < maxRawSize) { + rreAfterBufSize = maxRawSize; + if (rreAfterBuf == NULL) + rreAfterBuf = (char *)xalloc(rreAfterBufSize); + else + rreAfterBuf = (char *)xrealloc(rreAfterBuf, rreAfterBufSize); + } + + (*cl->translateFn)(cl->translateLookupTable, + &(cl->screen->rfbServerFormat), + &cl->format, fbptr, rreBeforeBuf, + cl->screen->paddedWidthInBytes, w, h); + + switch (cl->format.bitsPerPixel) { + case 8: + nSubrects = subrectEncode8((CARD8 *)rreBeforeBuf, w, h); + break; + case 16: + nSubrects = subrectEncode16((CARD16 *)rreBeforeBuf, w, h); + break; + case 32: + nSubrects = subrectEncode32((CARD32 *)rreBeforeBuf, w, h); + break; + default: + rfbLog("getBgColour: bpp %d?\n",cl->format.bitsPerPixel); + exit(1); + } + + if (nSubrects < 0) { + + /* RRE encoding was too large, use raw */ + + return rfbSendRectEncodingRaw(cl, x, y, w, h); + } + + cl->rfbRectanglesSent[rfbEncodingRRE]++; + cl->rfbBytesSent[rfbEncodingRRE] += (sz_rfbFramebufferUpdateRectHeader + + sz_rfbRREHeader + rreAfterBufLen); + + if (cl->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader + > UPDATE_BUF_SIZE) + { + if (!rfbSendUpdateBuf(cl)) + return FALSE; + } + + rect.r.x = Swap16IfLE(x); + rect.r.y = Swap16IfLE(y); + rect.r.w = Swap16IfLE(w); + rect.r.h = Swap16IfLE(h); + rect.encoding = Swap32IfLE(rfbEncodingRRE); + + memcpy(&cl->updateBuf[cl->ublen], (char *)&rect, + sz_rfbFramebufferUpdateRectHeader); + cl->ublen += sz_rfbFramebufferUpdateRectHeader; + + hdr.nSubrects = Swap32IfLE(nSubrects); + + memcpy(&cl->updateBuf[cl->ublen], (char *)&hdr, sz_rfbRREHeader); + cl->ublen += sz_rfbRREHeader; + + for (i = 0; i < rreAfterBufLen;) { + + int bytesToCopy = UPDATE_BUF_SIZE - cl->ublen; + + if (i + bytesToCopy > rreAfterBufLen) { + bytesToCopy = rreAfterBufLen - i; + } + + memcpy(&cl->updateBuf[cl->ublen], &rreAfterBuf[i], bytesToCopy); + + cl->ublen += bytesToCopy; + i += bytesToCopy; + + if (cl->ublen == UPDATE_BUF_SIZE) { + if (!rfbSendUpdateBuf(cl)) + return FALSE; + } + } + + return TRUE; +} + + + +/* + * subrectEncode() encodes the given multicoloured rectangle as a background + * colour overwritten by single-coloured rectangles. It returns the number + * of subrectangles in the encoded buffer, or -1 if subrect encoding won't + * fit in the buffer. It puts the encoded rectangles in rreAfterBuf. The + * single-colour rectangle partition is not optimal, but does find the biggest + * horizontal or vertical rectangle top-left anchored to each consecutive + * coordinate position. + * + * The coding scheme is simply [...] where each + * is []. + */ + +#define DEFINE_SUBRECT_ENCODE(bpp) \ +static int \ +subrectEncode##bpp(data,w,h) \ + CARD##bpp *data; \ + int w; \ + int h; \ +{ \ + CARD##bpp cl; \ + rfbRectangle subrect; \ + int x,y; \ + int i,j; \ + int hx=0,hy,vx=0,vy; \ + int hyflag; \ + CARD##bpp *seg; \ + CARD##bpp *line; \ + int hw,hh,vw,vh; \ + int thex,they,thew,theh; \ + int numsubs = 0; \ + int newLen; \ + CARD##bpp bg = (CARD##bpp)getBgColour((char*)data,w*h,bpp); \ + \ + *((CARD##bpp*)rreAfterBuf) = bg; \ + \ + rreAfterBufLen = (bpp/8); \ + \ + for (y=0; y 0) && (i >= hx)) {hy += 1;} else {hyflag = 0;} \ + } \ + vy = j-1; \ + \ + /* We now have two possible subrects: (x,y,hx,hy) and (x,y,vx,vy) \ + * We'll choose the bigger of the two. \ + */ \ + hw = hx-x+1; \ + hh = hy-y+1; \ + vw = vx-x+1; \ + vh = vy-y+1; \ + \ + thex = x; \ + they = y; \ + \ + if ((hw*hh) > (vw*vh)) { \ + thew = hw; \ + theh = hh; \ + } else { \ + thew = vw; \ + theh = vh; \ + } \ + \ + subrect.x = Swap16IfLE(thex); \ + subrect.y = Swap16IfLE(they); \ + subrect.w = Swap16IfLE(thew); \ + subrect.h = Swap16IfLE(theh); \ + \ + newLen = rreAfterBufLen + (bpp/8) + sz_rfbRectangle; \ + if ((newLen > (w * h * (bpp/8))) || (newLen > rreAfterBufSize)) \ + return -1; \ + \ + numsubs += 1; \ + *((CARD##bpp*)(rreAfterBuf + rreAfterBufLen)) = cl; \ + rreAfterBufLen += (bpp/8); \ + memcpy(&rreAfterBuf[rreAfterBufLen],&subrect,sz_rfbRectangle); \ + rreAfterBufLen += sz_rfbRectangle; \ + \ + /* \ + * Now mark the subrect as done. \ + */ \ + for (j=they; j < (they+theh); j++) { \ + for (i=thex; i < (thex+thew); i++) { \ + data[j*w+i] = bg; \ + } \ + } \ + } \ + } \ + } \ + \ + return numsubs; \ +} + +DEFINE_SUBRECT_ENCODE(8) +DEFINE_SUBRECT_ENCODE(16) +DEFINE_SUBRECT_ENCODE(32) + + +/* + * getBgColour() gets the most prevalent colour in a byte array. + */ +static CARD32 +getBgColour(data,size,bpp) + char *data; + int size; + int bpp; +{ + +#define NUMCLRS 256 + + static int counts[NUMCLRS]; + int i,j,k; + + int maxcount = 0; + CARD8 maxclr = 0; + + if (bpp != 8) { + if (bpp == 16) { + return ((CARD16 *)data)[0]; + } else if (bpp == 32) { + return ((CARD32 *)data)[0]; + } else { + rfbLog("getBgColour: bpp %d?\n",bpp); + exit(1); + } + } + + for (i=0; i= NUMCLRS) { + rfbLog("getBgColour: unusual colour = %d\n", k); + exit(1); + } + counts[k] += 1; + if (counts[k] > maxcount) { + maxcount = counts[k]; + maxclr = ((CARD8 *)data)[j]; + } + } + + return maxclr; +} diff --git a/sockets.c b/sockets.c new file mode 100644 index 0000000..c0ac1dc --- /dev/null +++ b/sockets.c @@ -0,0 +1,450 @@ +/* + * sockets.c - deal with TCP & UDP sockets. + * + * This code should be independent of any changes in the RFB protocol. It just + * deals with the X server scheduling stuff, calling rfbNewClientConnection and + * rfbProcessClientMessage to actually deal with the protocol. If a socket + * needs to be closed for any reason then rfbCloseClient should be called, and + * this in turn will call rfbClientConnectionGone. To make an active + * connection out, call rfbConnect - note that this does _not_ call + * rfbNewClientConnection. + * + * This file is divided into two types of function. Those beginning with + * "rfb" are specific to sockets using the RFB protocol. Those without the + * "rfb" prefix are more general socket routines (which are used by the http + * code). + * + * Thanks to Karl Hakimian for pointing out that some platforms return EAGAIN + * not EWOULDBLOCK. + */ + +/* + * OSXvnc Copyright (C) 2001 Dan McGuirk . + * Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge. + * All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include +#include +#include +#if defined(__linux__) && defined(NEED_TIMEVAL) +struct timeval +{ + long int tv_sec,tv_usec; +} +; +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rfb.h" + +int rfbMaxClientWait = 20000; /* time (ms) after which we decide client has + gone away - needed to stop us hanging */ + +/* + * rfbInitSockets sets up the TCP and UDP sockets to listen for RFB + * connections. It does nothing if called again. + */ + +void +rfbInitSockets(rfbScreenInfoPtr rfbScreen) +{ + if (rfbScreen->socketInitDone) + return; + + rfbScreen->socketInitDone = TRUE; + + if (rfbScreen->inetdSock != -1) { + const int one = 1; + + if (fcntl(rfbScreen->inetdSock, F_SETFL, O_NONBLOCK) < 0) { + rfbLogPerror("fcntl"); + exit(1); + } + + if (setsockopt(rfbScreen->inetdSock, IPPROTO_TCP, TCP_NODELAY, + (char *)&one, sizeof(one)) < 0) { + rfbLogPerror("setsockopt"); + exit(1); + } + + FD_ZERO(&(rfbScreen->allFds)); + FD_SET(rfbScreen->inetdSock, &(rfbScreen->allFds)); + rfbScreen->maxFd = rfbScreen->inetdSock; + return; + } + + rfbLog("Listening for VNC connections on TCP port %d\n", rfbScreen->rfbPort); + + if ((rfbScreen->rfbListenSock = ListenOnTCPPort(rfbScreen->rfbPort)) < 0) { + rfbLogPerror("ListenOnTCPPort"); + exit(1); + } + + FD_ZERO(&(rfbScreen->allFds)); + FD_SET(rfbScreen->rfbListenSock, &(rfbScreen->allFds)); + rfbScreen->maxFd = rfbScreen->rfbListenSock; + + if (rfbScreen->udpPort != 0) { + rfbLog("rfbInitSockets: listening for input on UDP port %d\n",rfbScreen->udpPort); + + if ((rfbScreen->udpSock = ListenOnUDPPort(rfbScreen->udpPort)) < 0) { + rfbLogPerror("ListenOnUDPPort"); + exit(1); + } + FD_SET(rfbScreen->udpSock, &(rfbScreen->allFds)); + rfbScreen->maxFd = max(rfbScreen->udpSock,rfbScreen->maxFd); + } +} + + +/* + * rfbCheckFds is called from ProcessInputEvents to check for input on the RFB + * socket(s). If there is input to process, the appropriate function in the + * RFB server code will be called (rfbNewClientConnection, + * rfbProcessClientMessage, etc). + */ + +void +rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec) +{ + int nfds; + fd_set fds; + struct timeval tv; + struct sockaddr_in addr; + int addrlen = sizeof(addr); + char buf[6]; + const int one = 1; + int sock; + rfbClientPtr cl; + + if (!rfbScreen->inetdInitDone && rfbScreen->inetdSock != -1) { + rfbNewClientConnection(rfbScreen,rfbScreen->inetdSock); + rfbScreen->inetdInitDone = TRUE; + } + + memcpy((char *)&fds, (char *)&(rfbScreen->allFds), sizeof(fd_set)); + tv.tv_sec = 0; + tv.tv_usec = usec; + nfds = select(rfbScreen->maxFd + 1, &fds, NULL, NULL, &tv); + if (nfds == 0) { + return; + } + if (nfds < 0) { + rfbLogPerror("rfbCheckFds: select"); + return; + } + + if (rfbScreen->rfbListenSock != -1 && FD_ISSET(rfbScreen->rfbListenSock, &fds)) { + + if ((sock = accept(rfbScreen->rfbListenSock, + (struct sockaddr *)&addr, &addrlen)) < 0) { + rfbLogPerror("rfbCheckFds: accept"); + return; + } + + if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) { + rfbLogPerror("rfbCheckFds: fcntl"); + close(sock); + return; + } + + if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, + (char *)&one, sizeof(one)) < 0) { + rfbLogPerror("rfbCheckFds: setsockopt"); + close(sock); + return; + } + + fprintf(stderr,"\n"); + rfbLog("Got connection from client %s\n", inet_ntoa(addr.sin_addr)); + + FD_SET(sock, &(rfbScreen->allFds)); + rfbScreen->maxFd = max(sock,rfbScreen->maxFd); + + rfbNewClient(rfbScreen,sock); + + FD_CLR(rfbScreen->rfbListenSock, &fds); + if (--nfds == 0) + return; + } + + if ((rfbScreen->udpSock != -1) && FD_ISSET(rfbScreen->udpSock, &fds)) { + + if (recvfrom(rfbScreen->udpSock, buf, 1, MSG_PEEK, + (struct sockaddr *)&addr, &addrlen) < 0) { + + rfbLogPerror("rfbCheckFds: UDP: recvfrom"); + rfbDisconnectUDPSock(rfbScreen); + + } else { + + if (!rfbScreen->udpSockConnected || + (memcmp(&addr, &rfbScreen->udpRemoteAddr, addrlen) != 0)) + { + /* new remote end */ + rfbLog("rfbCheckFds: UDP: got connection\n"); + + memcpy(&rfbScreen->udpRemoteAddr, &addr, addrlen); + rfbScreen->udpSockConnected = TRUE; + + if (connect(rfbScreen->udpSock, + (struct sockaddr *)&addr, addrlen) < 0) { + rfbLogPerror("rfbCheckFds: UDP: connect"); + rfbDisconnectUDPSock(rfbScreen); + return; + } + + rfbNewUDPConnection(rfbScreen,rfbScreen->udpSock); + } + + //TODO: UDP also needs a client + //rfbProcessUDPInput(rfbScreen,rfbScreen->udpSock); + } + + FD_CLR(rfbScreen->udpSock, &fds); + if (--nfds == 0) + return; + } + + for (cl = rfbScreen->rfbClientHead; cl; cl=cl->next) { + if (FD_ISSET(cl->sock, &fds) && FD_ISSET(cl->sock, &(rfbScreen->allFds))) { + rfbProcessClientMessage(cl); + } + } +} + + +void +rfbDisconnectUDPSock(rfbScreenInfoPtr rfbScreen) +{ + rfbScreen->udpSockConnected = FALSE; +} + + + +void +rfbCloseClient(cl) + rfbClientPtr cl; +{ + FD_CLR(cl->sock,&(cl->screen->allFds)); + rfbClientConnectionGone(cl); + close(cl->sock); + cl->sock = -1; +} + + +/* + * ReadExact reads an exact number of bytes from a client. Returns 1 if + * those bytes have been read, 0 if the other end has closed, or -1 if an error + * occurred (errno is set to ETIMEDOUT if it timed out). + */ + +int +ReadExact(cl, buf, len) + rfbClientPtr cl; + char *buf; + int len; +{ + int sock = cl->sock; + int n; + fd_set fds; + struct timeval tv; + + while (len > 0) { + n = read(sock, buf, len); + + if (n > 0) { + + buf += n; + len -= n; + + } else if (n == 0) { + + return 0; + + } else { + if (errno != EWOULDBLOCK && errno != EAGAIN) { + return n; + } + + FD_ZERO(&fds); + FD_SET(sock, &fds); + tv.tv_sec = rfbMaxClientWait / 1000; + tv.tv_usec = (rfbMaxClientWait % 1000) * 1000; + n = select(sock+1, &fds, NULL, NULL, &tv); + if (n < 0) { + rfbLogPerror("ReadExact: select"); + return n; + } + if (n == 0) { + errno = ETIMEDOUT; + return -1; + } + } + } + return 1; +} + + + +/* + * WriteExact writes an exact number of bytes to a client. Returns 1 if + * those bytes have been written, or -1 if an error occurred (errno is set to + * ETIMEDOUT if it timed out). + */ + +int +WriteExact(cl, buf, len) + rfbClientPtr cl; + char *buf; + int len; +{ + int sock = cl->sock; + int n; + fd_set fds; + struct timeval tv; + int totalTimeWaited = 0; + +#ifdef HAVE_PTHREADS + pthread_mutex_lock(&cl->outputMutex); +#endif + while (len > 0) { + n = write(sock, buf, len); + + if (n > 0) { + + buf += n; + len -= n; + + } else if (n == 0) { + + rfbLog("WriteExact: write returned 0?\n"); + exit(1); + + } else { + if (errno != EWOULDBLOCK && errno != EAGAIN) { +#ifdef HAVE_PTHREADS + pthread_mutex_unlock(&cl->outputMutex); +#endif + return n; + } + + /* Retry every 5 seconds until we exceed rfbMaxClientWait. We + need to do this because select doesn't necessarily return + immediately when the other end has gone away */ + + FD_ZERO(&fds); + FD_SET(sock, &fds); + tv.tv_sec = 5; + tv.tv_usec = 0; + n = select(sock+1, NULL, &fds, NULL, &tv); + if (n < 0) { + rfbLogPerror("WriteExact: select"); +#ifdef HAVE_PTHREADS + pthread_mutex_unlock(&cl->outputMutex); +#endif + return n; + } + if (n == 0) { + totalTimeWaited += 5000; + if (totalTimeWaited >= rfbMaxClientWait) { + errno = ETIMEDOUT; +#ifdef HAVE_PTHREADS + pthread_mutex_unlock(&cl->outputMutex); +#endif + return -1; + } + } else { + totalTimeWaited = 0; + } + } + } +#ifdef HAVE_PTHREADS + pthread_mutex_unlock(&cl->outputMutex); +#endif + return 1; +} + + +int +ListenOnTCPPort(port) + int port; +{ + struct sockaddr_in addr; + int sock; + int one = 1; + + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + //addr.sin_addr.s_addr = interface.s_addr; + addr.sin_addr.s_addr = INADDR_ANY; + + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + return -1; + } + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, + (char *)&one, sizeof(one)) < 0) { + close(sock); + return -1; + } + if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + close(sock); + return -1; + } + if (listen(sock, 5) < 0) { + close(sock); + return -1; + } + + return sock; +} + +int +ListenOnUDPPort(port) + int port; +{ + struct sockaddr_in addr; + int sock; + int one = 1; + + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + //addr.sin_addr.s_addr = interface.s_addr; + addr.sin_addr.s_addr = INADDR_ANY; + + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + return -1; + } + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, + (char *)&one, sizeof(one)) < 0) { + return -1; + } + if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + return -1; + } + + return sock; +} diff --git a/stats.c b/stats.c new file mode 100644 index 0000000..f712021 --- /dev/null +++ b/stats.c @@ -0,0 +1,99 @@ +/* + * stats.c + */ + +/* + * OSXvnc Copyright (C) 2001 Dan McGuirk . + * Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge. + * All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include +#include +#include "rfb.h" + +static char* encNames[] = { + "raw", "copyRect", "RRE", "[encoding 3]", "CoRRE", "hextile", + "zlib", "tight", "[encoding 8]", "[encoding 9]" +}; + + +void +rfbResetStats(rfbClientPtr cl) +{ + int i; + for (i = 0; i < MAX_ENCODINGS; i++) { + cl->rfbBytesSent[i] = 0; + cl->rfbRectanglesSent[i] = 0; + } + cl->rfbLastRectMarkersSent = 0; + cl->rfbLastRectBytesSent = 0; + cl->rfbCursorBytesSent = 0; + cl->rfbCursorUpdatesSent = 0; + cl->rfbFramebufferUpdateMessagesSent = 0; + cl->rfbRawBytesEquivalent = 0; + cl->rfbKeyEventsRcvd = 0; + cl->rfbPointerEventsRcvd = 0; +} + +void +rfbPrintStats(rfbClientPtr cl) +{ + int i; + int totalRectanglesSent = 0; + int totalBytesSent = 0; + + rfbLog("Statistics:\n"); + + if ((cl->rfbKeyEventsRcvd != 0) || (cl->rfbPointerEventsRcvd != 0)) + rfbLog(" key events received %d, pointer events %d\n", + cl->rfbKeyEventsRcvd, cl->rfbPointerEventsRcvd); + + for (i = 0; i < MAX_ENCODINGS; i++) { + totalRectanglesSent += cl->rfbRectanglesSent[i]; + totalBytesSent += cl->rfbBytesSent[i]; + } + + rfbLog(" framebuffer updates %d, rectangles %d, bytes %d\n", + cl->rfbFramebufferUpdateMessagesSent, totalRectanglesSent, + totalBytesSent); + + if (cl->rfbLastRectMarkersSent != 0) + rfbLog(" LastRect markers %d, bytes %d\n", + cl->rfbLastRectMarkersSent, cl->rfbLastRectBytesSent); + + if (cl->rfbCursorUpdatesSent != 0) + rfbLog(" cursor shape updates %d, bytes %d\n", + cl->rfbCursorUpdatesSent, cl->rfbCursorBytesSent); + + for (i = 0; i < MAX_ENCODINGS; i++) { + if (cl->rfbRectanglesSent[i] != 0) + rfbLog(" %s rectangles %d, bytes %d\n", + encNames[i], cl->rfbRectanglesSent[i], cl->rfbBytesSent[i]); + } + + if ((totalBytesSent - cl->rfbBytesSent[rfbEncodingCopyRect]) != 0) { + rfbLog(" raw bytes equivalent %d, compression ratio %f\n", + cl->rfbRawBytesEquivalent, + (double)cl->rfbRawBytesEquivalent + / (double)(totalBytesSent + - cl->rfbBytesSent[rfbEncodingCopyRect]- + cl->rfbCursorBytesSent - + cl->rfbLastRectBytesSent)); + } +} diff --git a/storepasswd.c b/storepasswd.c new file mode 100644 index 0000000..6825d0d --- /dev/null +++ b/storepasswd.c @@ -0,0 +1,46 @@ +/* + * OSXvnc Copyright (C) 2001 Dan McGuirk . + * Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge. + * All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include +#include "vncauth.h" + +void usage(void) +{ + printf("\nusage: storepasswd \n\n"); + + printf("Stores a password in encrypted format.\n"); + printf("The resulting file can be used with the -rfbauth argument to OSXvnc.\n\n"); + exit(1); +} + +int main(int argc, char *argv[]) +{ + if (argc != 3) + usage(); + + if (vncEncryptAndStorePasswd(argv[1], argv[2]) != 0) { + printf("storing password failed.\n"); + return 1; + } else { + printf("storing password succeeded.\n"); + return 0; + } +} diff --git a/tableinitcmtemplate.c b/tableinitcmtemplate.c new file mode 100644 index 0000000..13de763 --- /dev/null +++ b/tableinitcmtemplate.c @@ -0,0 +1,84 @@ +/* + * tableinitcmtemplate.c - template for initialising lookup tables for + * translation from a colour map to true colour. + * + * This file shouldn't be compiled. It is included multiple times by + * translate.c, each time with a different definition of the macro OUT. + * For each value of OUT, this file defines a function which allocates an + * appropriately sized lookup table and initialises it. + * + * I know this code isn't nice to read because of all the macros, but + * efficiency is important here. + */ + +/* + * OSXvnc Copyright (C) 2001 Dan McGuirk . + * Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge. + * All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#if !defined(OUT) +#error "This file shouldn't be compiled." +#error "It is included as part of translate.c" +#endif + +#define OUT_T CONCAT2E(CARD,OUT) +#define SwapOUT(x) CONCAT2E(Swap,OUT(x)) +#define rfbInitColourMapSingleTableOUT \ + CONCAT2E(rfbInitColourMapSingleTable,OUT) + +static void +rfbInitColourMapSingleTableOUT (char **table, rfbPixelFormat *in, + rfbPixelFormat *out) +{ + int i, r, g, b; + OUT_T *t; + EntryPtr pent; + int nEntries = 1 << in->bitsPerPixel; + + if (*table) free(*table); + *table = (char *)malloc(nEntries * sizeof(OUT_T)); + t = (OUT_T *)*table; + + pent = (EntryPtr)&rfbInstalledColormap->red[0]; + + for (i = 0; i < nEntries; i++) { + if (pent->fShared) { + r = pent->co.shco.red->color; + g = pent->co.shco.green->color; + b = pent->co.shco.blue->color; + } else { + r = pent->co.local.red; + g = pent->co.local.green; + b = pent->co.local.blue; + } + t[i] = ((((r * out->redMax + 32767) / 65535) << out->redShift) | + (((g * out->greenMax + 32767) / 65535) << out->greenShift) | + (((b * out->blueMax + 32767) / 65535) << out->blueShift)); +#if (OUT != 8) + if (out->bigEndian != in->bigEndian) { + t[i] = SwapOUT(t[i]); + } +#endif + pent++; + } +} + +#undef OUT_T +#undef SwapOUT +#undef rfbInitColourMapSingleTableOUT diff --git a/tableinittctemplate.c b/tableinittctemplate.c new file mode 100644 index 0000000..e5f94d5 --- /dev/null +++ b/tableinittctemplate.c @@ -0,0 +1,142 @@ +/* + * tableinittctemplate.c - template for initialising lookup tables for + * truecolour to truecolour translation. + * + * This file shouldn't be compiled. It is included multiple times by + * translate.c, each time with a different definition of the macro OUT. + * For each value of OUT, this file defines two functions for initialising + * lookup tables. One is for truecolour translation using a single lookup + * table, the other is for truecolour translation using three separate + * lookup tables for the red, green and blue values. + * + * I know this code isn't nice to read because of all the macros, but + * efficiency is important here. + */ + +/* + * OSXvnc Copyright (C) 2001 Dan McGuirk . + * Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge. + * All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#if !defined(OUT) +#error "This file shouldn't be compiled." +#error "It is included as part of translate.c" +#endif + +#define OUT_T CONCAT2E(CARD,OUT) +#define SwapOUT(x) CONCAT2E(Swap,OUT(x)) +#define rfbInitTrueColourSingleTableOUT \ + CONCAT2E(rfbInitTrueColourSingleTable,OUT) +#define rfbInitTrueColourRGBTablesOUT CONCAT2E(rfbInitTrueColourRGBTables,OUT) +#define rfbInitOneRGBTableOUT CONCAT2E(rfbInitOneRGBTable,OUT) + +static void +rfbInitOneRGBTableOUT (OUT_T *table, int inMax, int outMax, int outShift, + int swap); + + +/* + * rfbInitTrueColourSingleTable sets up a single lookup table for truecolour + * translation. + */ + +static void +rfbInitTrueColourSingleTableOUT (char **table, rfbPixelFormat *in, + rfbPixelFormat *out) +{ + int i; + int inRed, inGreen, inBlue, outRed, outGreen, outBlue; + OUT_T *t; + int nEntries = 1 << in->bitsPerPixel; + + if (*table) free(*table); + *table = (char *)xalloc(nEntries * sizeof(OUT_T)); + t = (OUT_T *)*table; + + for (i = 0; i < nEntries; i++) { + inRed = (i >> in->redShift) & in->redMax; + inGreen = (i >> in->greenShift) & in->greenMax; + inBlue = (i >> in->blueShift) & in->blueMax; + + outRed = (inRed * out->redMax + in->redMax / 2) / in->redMax; + outGreen = (inGreen * out->greenMax + in->greenMax / 2) / in->greenMax; + outBlue = (inBlue * out->blueMax + in->blueMax / 2) / in->blueMax; + + t[i] = ((outRed << out->redShift) | + (outGreen << out->greenShift) | + (outBlue << out->blueShift)); +#if (OUT != 8) + if (out->bigEndian != in->bigEndian) { + t[i] = SwapOUT(t[i]); + } +#endif + } +} + + +/* + * rfbInitTrueColourRGBTables sets up three separate lookup tables for the + * red, green and blue values. + */ + +static void +rfbInitTrueColourRGBTablesOUT (char **table, rfbPixelFormat *in, + rfbPixelFormat *out) +{ + OUT_T *redTable; + OUT_T *greenTable; + OUT_T *blueTable; + + if (*table) free(*table); + *table = (char *)xalloc((in->redMax + in->greenMax + in->blueMax + 3) + * sizeof(OUT_T)); + redTable = (OUT_T *)*table; + greenTable = redTable + in->redMax + 1; + blueTable = greenTable + in->greenMax + 1; + + rfbInitOneRGBTableOUT (redTable, in->redMax, out->redMax, + out->redShift, (out->bigEndian != in->bigEndian)); + rfbInitOneRGBTableOUT (greenTable, in->greenMax, out->greenMax, + out->greenShift, (out->bigEndian != in->bigEndian)); + rfbInitOneRGBTableOUT (blueTable, in->blueMax, out->blueMax, + out->blueShift, (out->bigEndian != in->bigEndian)); +} + +static void +rfbInitOneRGBTableOUT (OUT_T *table, int inMax, int outMax, int outShift, + int swap) +{ + int i; + int nEntries = inMax + 1; + + for (i = 0; i < nEntries; i++) { + table[i] = ((i * outMax + inMax / 2) / inMax) << outShift; +#if (OUT != 8) + if (swap) { + table[i] = SwapOUT(table[i]); + } +#endif + } +} + +#undef OUT_T +#undef SwapOUT +#undef rfbInitTrueColourSingleTableOUT +#undef rfbInitTrueColourRGBTablesOUT +#undef rfbInitOneRGBTableOUT diff --git a/tabletranstemplate.c b/tabletranstemplate.c new file mode 100644 index 0000000..0d69f19 --- /dev/null +++ b/tabletranstemplate.c @@ -0,0 +1,117 @@ +/* + * tabletranstemplate.c - template for translation using lookup tables. + * + * This file shouldn't be compiled. It is included multiple times by + * translate.c, each time with different definitions of the macros IN and OUT. + * + * For each pair of values IN and OUT, this file defines two functions for + * translating a given rectangle of pixel data. One uses a single lookup + * table, and the other uses three separate lookup tables for the red, green + * and blue values. + * + * I know this code isn't nice to read because of all the macros, but + * efficiency is important here. + */ + +/* + * OSXvnc Copyright (C) 2001 Dan McGuirk . + * Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge. + * All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#if !defined(IN) || !defined(OUT) +#error "This file shouldn't be compiled." +#error "It is included as part of translate.c" +#endif + +#define IN_T CONCAT2E(CARD,IN) +#define OUT_T CONCAT2E(CARD,OUT) +#define rfbTranslateWithSingleTableINtoOUT \ + CONCAT4E(rfbTranslateWithSingleTable,IN,to,OUT) +#define rfbTranslateWithRGBTablesINtoOUT \ + CONCAT4E(rfbTranslateWithRGBTables,IN,to,OUT) + +/* + * rfbTranslateWithSingleTableINtoOUT translates a rectangle of pixel data + * using a single lookup table. + */ + +static void +rfbTranslateWithSingleTableINtoOUT (char *table, rfbPixelFormat *in, + rfbPixelFormat *out, + char *iptr, char *optr, + int bytesBetweenInputLines, + int width, int height) +{ + IN_T *ip = (IN_T *)iptr; + OUT_T *op = (OUT_T *)optr; + int ipextra = bytesBetweenInputLines / sizeof(IN_T) - width; + OUT_T *opLineEnd; + OUT_T *t = (OUT_T *)table; + + while (height > 0) { + opLineEnd = op + width; + + while (op < opLineEnd) { + *(op++) = t[*(ip++)]; + } + + ip += ipextra; + height--; + } +} + + +/* + * rfbTranslateWithRGBTablesINtoOUT translates a rectangle of pixel data + * using three separate lookup tables for the red, green and blue values. + */ + +static void +rfbTranslateWithRGBTablesINtoOUT (char *table, rfbPixelFormat *in, + rfbPixelFormat *out, + char *iptr, char *optr, + int bytesBetweenInputLines, + int width, int height) +{ + IN_T *ip = (IN_T *)iptr; + OUT_T *op = (OUT_T *)optr; + int ipextra = bytesBetweenInputLines / sizeof(IN_T) - width; + OUT_T *opLineEnd; + OUT_T *redTable = (OUT_T *)table; + OUT_T *greenTable = redTable + in->redMax + 1; + OUT_T *blueTable = greenTable + in->greenMax + 1; + + while (height > 0) { + opLineEnd = op + width; + + while (op < opLineEnd) { + *(op++) = (redTable[(*ip >> in->redShift) & in->redMax] | + greenTable[(*ip >> in->greenShift) & in->greenMax] | + blueTable[(*ip >> in->blueShift) & in->blueMax]); + ip++; + } + ip += ipextra; + height--; + } +} + +#undef IN_T +#undef OUT_T +#undef rfbTranslateWithSingleTableINtoOUT +#undef rfbTranslateWithRGBTablesINtoOUT diff --git a/tight.c b/tight.c new file mode 100644 index 0000000..509a6d8 --- /dev/null +++ b/tight.c @@ -0,0 +1,1772 @@ +/* + * tight.c + * + * Routines to implement Tight Encoding + */ + +/* + * Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved. + * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include +#include "rfb.h" +#include + + +/* Note: The following constant should not be changed. */ +#define TIGHT_MIN_TO_COMPRESS 12 + +/* May be set to TRUE with "-lazytight" Xvnc option. */ +Bool rfbTightDisableGradient = FALSE; + +/* This variable is set on every rfbSendRectEncodingTight() call. */ +static Bool usePixelFormat24; + + +/* Compression level stuff. The following array contains various + encoder parameters for each of 10 compression levels (0..9). + Last three parameters correspond to JPEG quality levels (0..9). */ + +typedef struct TIGHT_CONF_s { + int maxRectSize, maxRectWidth; + int monoMinRectSize, gradientMinRectSize; + int idxZlibLevel, monoZlibLevel, rawZlibLevel, gradientZlibLevel; + int gradientThreshold, gradientThreshold24; + int idxMaxColorsDivisor; + int jpegQuality, jpegThreshold, jpegThreshold24; +} TIGHT_CONF; + +static TIGHT_CONF tightConf[10] = { + { 512, 32, 6, 65536, 0, 0, 0, 0, 0, 0, 4, 20, 10000, 25000 }, + { 2048, 128, 6, 65536, 1, 1, 1, 0, 0, 0, 8, 30, 8000, 18000 }, + { 6144, 256, 8, 65536, 3, 3, 2, 0, 0, 0, 24, 40, 6500, 15000 }, + { 10240, 1024, 12, 65536, 5, 5, 3, 0, 0, 0, 32, 50, 5000, 12000 }, + { 16384, 2048, 12, 65536, 6, 6, 4, 0, 0, 0, 32, 55, 4000, 10000 }, + { 32768, 2048, 12, 4096, 7, 7, 5, 4, 150, 380, 32, 60, 3000, 8000 }, + { 65536, 2048, 16, 4096, 7, 7, 6, 4, 170, 420, 48, 65, 2000, 5000 }, + { 65536, 2048, 16, 4096, 8, 8, 7, 5, 180, 450, 64, 70, 1000, 2500 }, + { 65536, 2048, 32, 8192, 9, 9, 8, 6, 190, 475, 64, 75, 500, 1200 }, + { 65536, 2048, 32, 8192, 9, 9, 9, 6, 200, 500, 96, 80, 200, 500 } +}; + +static int compressLevel; +static int qualityLevel; + +/* Stuff dealing with palettes. */ + +typedef struct COLOR_LIST_s { + struct COLOR_LIST_s *next; + int idx; + CARD32 rgb; +} COLOR_LIST; + +typedef struct PALETTE_ENTRY_s { + COLOR_LIST *listNode; + int numPixels; +} PALETTE_ENTRY; + +typedef struct PALETTE_s { + PALETTE_ENTRY entry[256]; + COLOR_LIST *hash[256]; + COLOR_LIST list[256]; +} PALETTE; + +static int paletteNumColors, paletteMaxColors; +static CARD32 monoBackground, monoForeground; +static PALETTE palette; + +/* Pointers to dynamically-allocated buffers. */ + +static int tightBeforeBufSize = 0; +static char *tightBeforeBuf = NULL; + +static int tightAfterBufSize = 0; +static char *tightAfterBuf = NULL; + +static int *prevRowBuf = NULL; + + +/* Prototypes for static functions. */ + +static void FindBestSolidArea (rfbClientPtr cl, int x, int y, int w, int h, + CARD32 colorValue, int *w_ptr, int *h_ptr); +static void ExtendSolidArea (rfbClientPtr cl, int x, int y, int w, int h, + CARD32 colorValue, + int *x_ptr, int *y_ptr, int *w_ptr, int *h_ptr); +static Bool CheckSolidTile (rfbClientPtr cl, int x, int y, int w, int h, + CARD32 *colorPtr, Bool needSameColor); +static Bool CheckSolidTile8 (rfbClientPtr cl, int x, int y, int w, int h, + CARD32 *colorPtr, Bool needSameColor); +static Bool CheckSolidTile16 (rfbClientPtr cl, int x, int y, int w, int h, + CARD32 *colorPtr, Bool needSameColor); +static Bool CheckSolidTile32 (rfbClientPtr cl, int x, int y, int w, int h, + CARD32 *colorPtr, Bool needSameColor); + +static Bool SendRectSimple (rfbClientPtr cl, int x, int y, int w, int h); +static Bool SendSubrect (rfbClientPtr cl, int x, int y, int w, int h); +static Bool SendTightHeader (rfbClientPtr cl, int x, int y, int w, int h); + +static Bool SendSolidRect (rfbClientPtr cl); +static Bool SendMonoRect (rfbClientPtr cl, int w, int h); +static Bool SendIndexedRect (rfbClientPtr cl, int w, int h); +static Bool SendFullColorRect (rfbClientPtr cl, int w, int h); +static Bool SendGradientRect (rfbClientPtr cl, int w, int h); + +static Bool CompressData(rfbClientPtr cl, int streamId, int dataLen, + int zlibLevel, int zlibStrategy); +static Bool SendCompressedData(rfbClientPtr cl, int compressedLen); + +static void FillPalette8(int count); +static void FillPalette16(int count); +static void FillPalette32(int count); + +static void PaletteReset(void); +static int PaletteInsert(CARD32 rgb, int numPixels, int bpp); + +static void Pack24(rfbClientPtr cl, char *buf, rfbPixelFormat *fmt, int count); + +static void EncodeIndexedRect16(CARD8 *buf, int count); +static void EncodeIndexedRect32(CARD8 *buf, int count); + +static void EncodeMonoRect8(CARD8 *buf, int w, int h); +static void EncodeMonoRect16(CARD8 *buf, int w, int h); +static void EncodeMonoRect32(CARD8 *buf, int w, int h); + +static void FilterGradient24(rfbClientPtr cl, char *buf, rfbPixelFormat *fmt, int w, int h); +static void FilterGradient16(rfbClientPtr cl, CARD16 *buf, rfbPixelFormat *fmt, int w, int h); +static void FilterGradient32(rfbClientPtr cl, CARD32 *buf, rfbPixelFormat *fmt, int w, int h); + +static int DetectSmoothImage(rfbClientPtr cl, rfbPixelFormat *fmt, int w, int h); +static unsigned long DetectSmoothImage24(rfbClientPtr cl, rfbPixelFormat *fmt, int w, int h); +static unsigned long DetectSmoothImage16(rfbClientPtr cl, rfbPixelFormat *fmt, int w, int h); +static unsigned long DetectSmoothImage32(rfbClientPtr cl, rfbPixelFormat *fmt, int w, int h); + +static Bool SendJpegRect(rfbClientPtr cl, int x, int y, int w, int h, + int quality); +static void PrepareRowForJpeg(rfbClientPtr cl, CARD8 *dst, int x, int y, int count); +static void PrepareRowForJpeg24(rfbClientPtr cl, CARD8 *dst, int x, int y, int count); +static void PrepareRowForJpeg16(rfbClientPtr cl, CARD8 *dst, int x, int y, int count); +static void PrepareRowForJpeg32(rfbClientPtr cl, CARD8 *dst, int x, int y, int count); + +static void JpegInitDestination(j_compress_ptr cinfo); +static boolean JpegEmptyOutputBuffer(j_compress_ptr cinfo); +static void JpegTermDestination(j_compress_ptr cinfo); +static void JpegSetDstManager(j_compress_ptr cinfo); + + +/* + * Tight encoding implementation. + */ + +#define MIN_SPLIT_RECT_SIZE 4096 +#define MIN_SOLID_SUBRECT_SIZE 2048 +#define MAX_SPLIT_TILE_SIZE 16 + +int +rfbNumCodedRectsTight(cl, x, y, w, h) + rfbClientPtr cl; + int x, y, w, h; +{ + int maxRectSize, maxRectWidth; + int subrectMaxWidth, subrectMaxHeight; + + /* No matter how many rectangles we will send if LastRect markers + are used to terminate rectangle stream. */ + if (cl->enableLastRectEncoding && w * h >= MIN_SPLIT_RECT_SIZE) + return 0; + + maxRectSize = tightConf[cl->tightCompressLevel].maxRectSize; + maxRectWidth = tightConf[cl->tightCompressLevel].maxRectWidth; + + if (w > maxRectWidth || w * h > maxRectSize) { + subrectMaxWidth = (w > maxRectWidth) ? maxRectWidth : w; + subrectMaxHeight = maxRectSize / subrectMaxWidth; + return (((w - 1) / maxRectWidth + 1) * + ((h - 1) / subrectMaxHeight + 1)); + } else { + return 1; + } +} + +Bool +rfbSendRectEncodingTight(cl, x, y, w, h) + rfbClientPtr cl; + int x, y, w, h; +{ + CARD32 colorValue; + int dx, dy, dw, dh; + int x_best, y_best, w_best, h_best; + char *fbptr; + + if ( cl->format.depth == 24 && cl->format.redMax == 0xFF && + cl->format.greenMax == 0xFF && cl->format.blueMax == 0xFF ) { + usePixelFormat24 = TRUE; + } else { + usePixelFormat24 = FALSE; + } + + if (!cl->enableLastRectEncoding || w * h < MIN_SPLIT_RECT_SIZE) + return SendRectSimple(cl, x, y, w, h); + + /* Make sure we can write one pixel into tightBeforeBuf. */ + + if (tightBeforeBufSize < 4) { + tightBeforeBufSize = 4; + if (tightBeforeBuf == NULL) + tightBeforeBuf = (char *)xalloc(tightBeforeBufSize); + else + tightBeforeBuf = (char *)xrealloc(tightBeforeBuf, + tightBeforeBufSize); + } + + /* Try to find large solid-color areas and send them separately. */ + + for (dy = y; dy < y + h; dy += MAX_SPLIT_TILE_SIZE) { + + dh = (dy + MAX_SPLIT_TILE_SIZE <= y + h) ? + MAX_SPLIT_TILE_SIZE : (y + h - dy); + + for (dx = x; dx < x + w; dx += MAX_SPLIT_TILE_SIZE) { + + dw = (dx + MAX_SPLIT_TILE_SIZE <= x + w) ? + MAX_SPLIT_TILE_SIZE : (x + w - dx); + + if (CheckSolidTile(cl, dx, dy, dw, dh, &colorValue, FALSE)) { + + /* Get dimensions of solid-color area. */ + + FindBestSolidArea(cl, dx, dy, w - (dx - x), h - (dy - y), + colorValue, &w_best, &h_best); + + /* Make sure a solid rectangle is large enough + (or the whole rectangle is of the same color). */ + + if ( w_best * h_best != w * h && + w_best * h_best < MIN_SOLID_SUBRECT_SIZE ) + continue; + + /* Try to extend solid rectangle to maximum size. */ + + x_best = dx; y_best = dy; + ExtendSolidArea(cl, x, y, w, h, colorValue, + &x_best, &y_best, &w_best, &h_best); + + /* Send rectangles at top and left to solid-color area. */ + + if ( y_best != y && + !SendRectSimple(cl, x, y, w, y_best-y) ) + return FALSE; + if ( x_best != x && + !rfbSendRectEncodingTight(cl, x, y_best, + x_best-x, h_best) ) + return FALSE; + + /* Send solid-color rectangle. */ + + if (!SendTightHeader(cl, x_best, y_best, w_best, h_best)) + return FALSE; + + fbptr = (cl->screen->frameBuffer + + (cl->screen->paddedWidthInBytes * y_best) + + (x_best * (cl->screen->bitsPerPixel / 8))); + + (*cl->translateFn)(cl->translateLookupTable, &cl->screen->rfbServerFormat, + &cl->format, fbptr, tightBeforeBuf, + cl->screen->paddedWidthInBytes, 1, 1); + + if (!SendSolidRect(cl)) + return FALSE; + + /* Send remaining rectangles (at right and bottom). */ + + if ( x_best + w_best != x + w && + !rfbSendRectEncodingTight(cl, x_best+w_best, y_best, + w-(x_best-x)-w_best, h_best) ) + return FALSE; + if ( y_best + h_best != y + h && + !rfbSendRectEncodingTight(cl, x, y_best+h_best, + w, h-(y_best-y)-h_best) ) + return FALSE; + + /* Return after all recursive calls are done. */ + + return TRUE; + } + + } + + } + + /* No suitable solid-color rectangles found. */ + + return SendRectSimple(cl, x, y, w, h); +} + +static void +FindBestSolidArea(cl, x, y, w, h, colorValue, w_ptr, h_ptr) + rfbClientPtr cl; + int x, y, w, h; + CARD32 colorValue; + int *w_ptr, *h_ptr; +{ + int dx, dy, dw, dh; + int w_prev; + int w_best = 0, h_best = 0; + + w_prev = w; + + for (dy = y; dy < y + h; dy += MAX_SPLIT_TILE_SIZE) { + + dh = (dy + MAX_SPLIT_TILE_SIZE <= y + h) ? + MAX_SPLIT_TILE_SIZE : (y + h - dy); + dw = (w_prev > MAX_SPLIT_TILE_SIZE) ? + MAX_SPLIT_TILE_SIZE : w_prev; + + if (!CheckSolidTile(cl, x, dy, dw, dh, &colorValue, TRUE)) + break; + + for (dx = x + dw; dx < x + w_prev;) { + dw = (dx + MAX_SPLIT_TILE_SIZE <= x + w_prev) ? + MAX_SPLIT_TILE_SIZE : (x + w_prev - dx); + if (!CheckSolidTile(cl, dx, dy, dw, dh, &colorValue, TRUE)) + break; + dx += dw; + } + + w_prev = dx - x; + if (w_prev * (dy + dh - y) > w_best * h_best) { + w_best = w_prev; + h_best = dy + dh - y; + } + } + + *w_ptr = w_best; + *h_ptr = h_best; +} + +static void +ExtendSolidArea(cl, x, y, w, h, colorValue, x_ptr, y_ptr, w_ptr, h_ptr) + rfbClientPtr cl; + int x, y, w, h; + CARD32 colorValue; + int *x_ptr, *y_ptr, *w_ptr, *h_ptr; +{ + int cx, cy; + + /* Try to extend the area upwards. */ + for ( cy = *y_ptr - 1; + cy >= y && CheckSolidTile(cl, *x_ptr, cy, *w_ptr, 1, &colorValue, TRUE); + cy-- ); + *h_ptr += *y_ptr - (cy + 1); + *y_ptr = cy + 1; + + /* ... downwards. */ + for ( cy = *y_ptr + *h_ptr; + cy < y + h && + CheckSolidTile(cl, *x_ptr, cy, *w_ptr, 1, &colorValue, TRUE); + cy++ ); + *h_ptr += cy - (*y_ptr + *h_ptr); + + /* ... to the left. */ + for ( cx = *x_ptr - 1; + cx >= x && CheckSolidTile(cl, cx, *y_ptr, 1, *h_ptr, &colorValue, TRUE); + cx-- ); + *w_ptr += *x_ptr - (cx + 1); + *x_ptr = cx + 1; + + /* ... to the right. */ + for ( cx = *x_ptr + *w_ptr; + cx < x + w && + CheckSolidTile(cl, cx, *y_ptr, 1, *h_ptr, &colorValue, TRUE); + cx++ ); + *w_ptr += cx - (*x_ptr + *w_ptr); +} + +static Bool +CheckSolidTile(cl, x, y, w, h, colorPtr, needSameColor) + rfbClientPtr cl; + int x, y, w, h; + CARD32 *colorPtr; + Bool needSameColor; +{ + switch(cl->screen->rfbServerFormat.bitsPerPixel) { + case 32: + return CheckSolidTile32(cl, x, y, w, h, colorPtr, needSameColor); + case 16: + return CheckSolidTile16(cl, x, y, w, h, colorPtr, needSameColor); + default: + return CheckSolidTile8(cl, x, y, w, h, colorPtr, needSameColor); + } +} + +#define DEFINE_CHECK_SOLID_FUNCTION(bpp) \ + \ +static Bool \ +CheckSolidTile##bpp(cl, x, y, w, h, colorPtr, needSameColor) \ + rfbClientPtr cl; \ + int x, y; \ + CARD32 *colorPtr; \ + Bool needSameColor; \ +{ \ + CARD##bpp *fbptr; \ + CARD##bpp colorValue; \ + int dx, dy; \ + \ + fbptr = (CARD##bpp *) \ + &cl->screen->frameBuffer[y * cl->screen->paddedWidthInBytes + x * (bpp/8)]; \ + \ + colorValue = *fbptr; \ + if (needSameColor && (CARD32)colorValue != *colorPtr) \ + return FALSE; \ + \ + for (dy = 0; dy < h; dy++) { \ + for (dx = 0; dx < w; dx++) { \ + if (colorValue != fbptr[dx]) \ + return FALSE; \ + } \ + fbptr = (CARD##bpp *)((CARD8 *)fbptr + cl->screen->paddedWidthInBytes); \ + } \ + \ + *colorPtr = (CARD32)colorValue; \ + return TRUE; \ +} + +DEFINE_CHECK_SOLID_FUNCTION(8) +DEFINE_CHECK_SOLID_FUNCTION(16) +DEFINE_CHECK_SOLID_FUNCTION(32) + +static Bool +SendRectSimple(cl, x, y, w, h) + rfbClientPtr cl; + int x, y, w, h; +{ + int maxBeforeSize, maxAfterSize; + int maxRectSize, maxRectWidth; + int subrectMaxWidth, subrectMaxHeight; + int dx, dy; + int rw, rh; + + compressLevel = cl->tightCompressLevel; + qualityLevel = cl->tightQualityLevel; + maxRectSize = tightConf[compressLevel].maxRectSize; + maxRectWidth = tightConf[compressLevel].maxRectWidth; + + maxBeforeSize = maxRectSize * (cl->format.bitsPerPixel / 8); + maxAfterSize = maxBeforeSize + (maxBeforeSize + 99) / 100 + 12; + + if (tightBeforeBufSize < maxBeforeSize) { + tightBeforeBufSize = maxBeforeSize; + if (tightBeforeBuf == NULL) + tightBeforeBuf = (char *)xalloc(tightBeforeBufSize); + else + tightBeforeBuf = (char *)xrealloc(tightBeforeBuf, + tightBeforeBufSize); + } + + if (tightAfterBufSize < maxAfterSize) { + tightAfterBufSize = maxAfterSize; + if (tightAfterBuf == NULL) + tightAfterBuf = (char *)xalloc(tightAfterBufSize); + else + tightAfterBuf = (char *)xrealloc(tightAfterBuf, + tightAfterBufSize); + } + + if (w > maxRectWidth || w * h > maxRectSize) { + subrectMaxWidth = (w > maxRectWidth) ? maxRectWidth : w; + subrectMaxHeight = maxRectSize / subrectMaxWidth; + + for (dy = 0; dy < h; dy += subrectMaxHeight) { + for (dx = 0; dx < w; dx += maxRectWidth) { + rw = (dx + maxRectWidth < w) ? maxRectWidth : w - dx; + rh = (dy + subrectMaxHeight < h) ? subrectMaxHeight : h - dy; + if (!SendSubrect(cl, x+dx, y+dy, rw, rh)) + return FALSE; + } + } + } else { + if (!SendSubrect(cl, x, y, w, h)) + return FALSE; + } + + return TRUE; +} + +static Bool +SendSubrect(cl, x, y, w, h) + rfbClientPtr cl; + int x, y, w, h; +{ + char *fbptr; + Bool success = FALSE; + + if (!SendTightHeader(cl, x, y, w, h)) + return FALSE; + + fbptr = (cl->screen->frameBuffer + (cl->screen->paddedWidthInBytes * y) + + (x * (cl->screen->bitsPerPixel / 8))); + + (*cl->translateFn)(cl->translateLookupTable, &cl->screen->rfbServerFormat, + &cl->format, fbptr, tightBeforeBuf, + cl->screen->paddedWidthInBytes, w, h); + + paletteMaxColors = w * h / tightConf[compressLevel].idxMaxColorsDivisor; + if ( paletteMaxColors < 2 && + w * h >= tightConf[compressLevel].monoMinRectSize ) { + paletteMaxColors = 2; + } + switch (cl->format.bitsPerPixel) { + case 8: + FillPalette8(w * h); + break; + case 16: + FillPalette16(w * h); + break; + default: + FillPalette32(w * h); + } + + switch (paletteNumColors) { + case 0: + /* Truecolor image */ + if (DetectSmoothImage(cl, &cl->format, w, h)) { + if (qualityLevel != -1) { + success = SendJpegRect(cl, x, y, w, h, + tightConf[qualityLevel].jpegQuality); + } else { + success = SendGradientRect(cl, w, h); + } + } else { + success = SendFullColorRect(cl, w, h); + } + break; + case 1: + /* Solid rectangle */ + success = SendSolidRect(cl); + break; + case 2: + /* Two-color rectangle */ + success = SendMonoRect(cl, w, h); + break; + default: + /* Up to 256 different colors */ + if ( paletteNumColors > 64 && + qualityLevel != -1 && qualityLevel <= 3 && + DetectSmoothImage(cl, &cl->format, w, h) ) { + success = SendJpegRect(cl, x, y, w, h, + tightConf[qualityLevel].jpegQuality); + } else { + success = SendIndexedRect(cl, w, h); + } + } + return success; +} + +static Bool +SendTightHeader(cl, x, y, w, h) + rfbClientPtr cl; + int x, y, w, h; +{ + rfbFramebufferUpdateRectHeader rect; + + if (cl->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE) { + if (!rfbSendUpdateBuf(cl)) + return FALSE; + } + + rect.r.x = Swap16IfLE(x); + rect.r.y = Swap16IfLE(y); + rect.r.w = Swap16IfLE(w); + rect.r.h = Swap16IfLE(h); + rect.encoding = Swap32IfLE(rfbEncodingTight); + + memcpy(&cl->updateBuf[cl->ublen], (char *)&rect, + sz_rfbFramebufferUpdateRectHeader); + cl->ublen += sz_rfbFramebufferUpdateRectHeader; + + cl->rfbRectanglesSent[rfbEncodingTight]++; + cl->rfbBytesSent[rfbEncodingTight] += sz_rfbFramebufferUpdateRectHeader; + + return TRUE; +} + +/* + * Subencoding implementations. + */ + +static Bool +SendSolidRect(cl) + rfbClientPtr cl; +{ + int len; + + if (usePixelFormat24) { + Pack24(cl, tightBeforeBuf, &cl->format, 1); + len = 3; + } else + len = cl->format.bitsPerPixel / 8; + + if (cl->ublen + 1 + len > UPDATE_BUF_SIZE) { + if (!rfbSendUpdateBuf(cl)) + return FALSE; + } + + cl->updateBuf[cl->ublen++] = (char)(rfbTightFill << 4); + memcpy (&cl->updateBuf[cl->ublen], tightBeforeBuf, len); + cl->ublen += len; + + cl->rfbBytesSent[rfbEncodingTight] += len + 1; + + return TRUE; +} + +static Bool +SendMonoRect(cl, w, h) + rfbClientPtr cl; + int w, h; +{ + int streamId = 1; + int paletteLen, dataLen; + + if ( cl->ublen + 6 + 2 * cl->format.bitsPerPixel / 8 > UPDATE_BUF_SIZE ) { + if (!rfbSendUpdateBuf(cl)) + return FALSE; + } + + /* Prepare tight encoding header. */ + dataLen = (w + 7) / 8; + dataLen *= h; + + cl->updateBuf[cl->ublen++] = (streamId | rfbTightExplicitFilter) << 4; + cl->updateBuf[cl->ublen++] = rfbTightFilterPalette; + cl->updateBuf[cl->ublen++] = 1; + + /* Prepare palette, convert image. */ + switch (cl->format.bitsPerPixel) { + + case 32: + EncodeMonoRect32((CARD8 *)tightBeforeBuf, w, h); + + ((CARD32 *)tightAfterBuf)[0] = monoBackground; + ((CARD32 *)tightAfterBuf)[1] = monoForeground; + if (usePixelFormat24) { + Pack24(cl, tightAfterBuf, &cl->format, 2); + paletteLen = 6; + } else + paletteLen = 8; + + memcpy(&cl->updateBuf[cl->ublen], tightAfterBuf, paletteLen); + cl->ublen += paletteLen; + cl->rfbBytesSent[rfbEncodingTight] += 3 + paletteLen; + break; + + case 16: + EncodeMonoRect16((CARD8 *)tightBeforeBuf, w, h); + + ((CARD16 *)tightAfterBuf)[0] = (CARD16)monoBackground; + ((CARD16 *)tightAfterBuf)[1] = (CARD16)monoForeground; + + memcpy(&cl->updateBuf[cl->ublen], tightAfterBuf, 4); + cl->ublen += 4; + cl->rfbBytesSent[rfbEncodingTight] += 7; + break; + + default: + EncodeMonoRect8((CARD8 *)tightBeforeBuf, w, h); + + cl->updateBuf[cl->ublen++] = (char)monoBackground; + cl->updateBuf[cl->ublen++] = (char)monoForeground; + cl->rfbBytesSent[rfbEncodingTight] += 5; + } + + return CompressData(cl, streamId, dataLen, + tightConf[compressLevel].monoZlibLevel, + Z_DEFAULT_STRATEGY); +} + +static Bool +SendIndexedRect(cl, w, h) + rfbClientPtr cl; + int w, h; +{ + int streamId = 2; + int i, entryLen; + + if ( cl->ublen + 6 + paletteNumColors * cl->format.bitsPerPixel / 8 > + UPDATE_BUF_SIZE ) { + if (!rfbSendUpdateBuf(cl)) + return FALSE; + } + + /* Prepare tight encoding header. */ + cl->updateBuf[cl->ublen++] = (streamId | rfbTightExplicitFilter) << 4; + cl->updateBuf[cl->ublen++] = rfbTightFilterPalette; + cl->updateBuf[cl->ublen++] = (char)(paletteNumColors - 1); + + /* Prepare palette, convert image. */ + switch (cl->format.bitsPerPixel) { + + case 32: + EncodeIndexedRect32((CARD8 *)tightBeforeBuf, w * h); + + for (i = 0; i < paletteNumColors; i++) { + ((CARD32 *)tightAfterBuf)[i] = + palette.entry[i].listNode->rgb; + } + if (usePixelFormat24) { + Pack24(cl, tightAfterBuf, &cl->format, paletteNumColors); + entryLen = 3; + } else + entryLen = 4; + + memcpy(&cl->updateBuf[cl->ublen], tightAfterBuf, paletteNumColors * entryLen); + cl->ublen += paletteNumColors * entryLen; + cl->rfbBytesSent[rfbEncodingTight] += 3 + paletteNumColors * entryLen; + break; + + case 16: + EncodeIndexedRect16((CARD8 *)tightBeforeBuf, w * h); + + for (i = 0; i < paletteNumColors; i++) { + ((CARD16 *)tightAfterBuf)[i] = + (CARD16)palette.entry[i].listNode->rgb; + } + + memcpy(&cl->updateBuf[cl->ublen], tightAfterBuf, paletteNumColors * 2); + cl->ublen += paletteNumColors * 2; + cl->rfbBytesSent[rfbEncodingTight] += 3 + paletteNumColors * 2; + break; + + default: + return FALSE; /* Should never happen. */ + } + + return CompressData(cl, streamId, w * h, + tightConf[compressLevel].idxZlibLevel, + Z_DEFAULT_STRATEGY); +} + +static Bool +SendFullColorRect(cl, w, h) + rfbClientPtr cl; + int w, h; +{ + int streamId = 0; + int len; + + if (cl->ublen + TIGHT_MIN_TO_COMPRESS + 1 > UPDATE_BUF_SIZE) { + if (!rfbSendUpdateBuf(cl)) + return FALSE; + } + + cl->updateBuf[cl->ublen++] = 0x00; /* stream id = 0, no flushing, no filter */ + cl->rfbBytesSent[rfbEncodingTight]++; + + if (usePixelFormat24) { + Pack24(cl, tightBeforeBuf, &cl->format, w * h); + len = 3; + } else + len = cl->format.bitsPerPixel / 8; + + return CompressData(cl, streamId, w * h * len, + tightConf[compressLevel].rawZlibLevel, + Z_DEFAULT_STRATEGY); +} + +static Bool +SendGradientRect(cl, w, h) + rfbClientPtr cl; + int w, h; +{ + int streamId = 3; + int len; + + if (cl->format.bitsPerPixel == 8) + return SendFullColorRect(cl, w, h); + + if (cl->ublen + TIGHT_MIN_TO_COMPRESS + 2 > UPDATE_BUF_SIZE) { + if (!rfbSendUpdateBuf(cl)) + return FALSE; + } + + if (prevRowBuf == NULL) + prevRowBuf = (int *)xalloc(2048 * 3 * sizeof(int)); + + cl->updateBuf[cl->ublen++] = (streamId | rfbTightExplicitFilter) << 4; + cl->updateBuf[cl->ublen++] = rfbTightFilterGradient; + cl->rfbBytesSent[rfbEncodingTight] += 2; + + if (usePixelFormat24) { + FilterGradient24(cl, tightBeforeBuf, &cl->format, w, h); + len = 3; + } else if (cl->format.bitsPerPixel == 32) { + FilterGradient32(cl, (CARD32 *)tightBeforeBuf, &cl->format, w, h); + len = 4; + } else { + FilterGradient16(cl, (CARD16 *)tightBeforeBuf, &cl->format, w, h); + len = 2; + } + + return CompressData(cl, streamId, w * h * len, + tightConf[compressLevel].gradientZlibLevel, + Z_FILTERED); +} + +static Bool +CompressData(cl, streamId, dataLen, zlibLevel, zlibStrategy) + rfbClientPtr cl; + int streamId, dataLen, zlibLevel, zlibStrategy; +{ + z_streamp pz; + int err; + + if (dataLen < TIGHT_MIN_TO_COMPRESS) { + memcpy(&cl->updateBuf[cl->ublen], tightBeforeBuf, dataLen); + cl->ublen += dataLen; + cl->rfbBytesSent[rfbEncodingTight] += dataLen; + return TRUE; + } + + pz = &cl->zsStruct[streamId]; + + /* Initialize compression stream if needed. */ + if (!cl->zsActive[streamId]) { + pz->zalloc = Z_NULL; + pz->zfree = Z_NULL; + pz->opaque = Z_NULL; + + err = deflateInit2 (pz, zlibLevel, Z_DEFLATED, MAX_WBITS, + MAX_MEM_LEVEL, zlibStrategy); + if (err != Z_OK) + return FALSE; + + cl->zsActive[streamId] = TRUE; + cl->zsLevel[streamId] = zlibLevel; + } + + /* Prepare buffer pointers. */ + pz->next_in = (Bytef *)tightBeforeBuf; + pz->avail_in = dataLen; + pz->next_out = (Bytef *)tightAfterBuf; + pz->avail_out = tightAfterBufSize; + + /* Change compression parameters if needed. */ + if (zlibLevel != cl->zsLevel[streamId]) { + if (deflateParams (pz, zlibLevel, zlibStrategy) != Z_OK) { + return FALSE; + } + cl->zsLevel[streamId] = zlibLevel; + } + + /* Actual compression. */ + if ( deflate (pz, Z_SYNC_FLUSH) != Z_OK || + pz->avail_in != 0 || pz->avail_out == 0 ) { + return FALSE; + } + + return SendCompressedData(cl, tightAfterBufSize - pz->avail_out); +} + +static Bool SendCompressedData(cl, compressedLen) + rfbClientPtr cl; + int compressedLen; +{ + int i, portionLen; + + cl->updateBuf[cl->ublen++] = compressedLen & 0x7F; + cl->rfbBytesSent[rfbEncodingTight]++; + if (compressedLen > 0x7F) { + cl->updateBuf[cl->ublen-1] |= 0x80; + cl->updateBuf[cl->ublen++] = compressedLen >> 7 & 0x7F; + cl->rfbBytesSent[rfbEncodingTight]++; + if (compressedLen > 0x3FFF) { + cl->updateBuf[cl->ublen-1] |= 0x80; + cl->updateBuf[cl->ublen++] = compressedLen >> 14 & 0xFF; + cl->rfbBytesSent[rfbEncodingTight]++; + } + } + + for (i = 0; i < compressedLen; ) { + portionLen = compressedLen - i; + if (portionLen > UPDATE_BUF_SIZE - cl->ublen) + portionLen = UPDATE_BUF_SIZE - cl->ublen; + + memcpy(&cl->updateBuf[cl->ublen], &tightAfterBuf[i], portionLen); + + cl->ublen += portionLen; + i += portionLen; + + if (!rfbSendUpdateBuf(cl)) + return FALSE; + } + cl->rfbBytesSent[rfbEncodingTight] += compressedLen; + return TRUE; +} + +/* + * Code to determine how many different colors used in rectangle. + */ + +static void +FillPalette8(count) + int count; +{ + CARD8 *data = (CARD8 *)tightBeforeBuf; + CARD8 c0, c1; + int i, n0, n1; + + paletteNumColors = 0; + + c0 = data[0]; + for (i = 1; i < count && data[i] == c0; i++); + if (i == count) { + paletteNumColors = 1; + return; /* Solid rectangle */ + } + + if (paletteMaxColors < 2) + return; + + n0 = i; + c1 = data[i]; + n1 = 0; + for (i++; i < count; i++) { + if (data[i] == c0) { + n0++; + } else if (data[i] == c1) { + n1++; + } else + break; + } + if (i == count) { + if (n0 > n1) { + monoBackground = (CARD32)c0; + monoForeground = (CARD32)c1; + } else { + monoBackground = (CARD32)c1; + monoForeground = (CARD32)c0; + } + paletteNumColors = 2; /* Two colors */ + } +} + +#define DEFINE_FILL_PALETTE_FUNCTION(bpp) \ + \ +static void \ +FillPalette##bpp(count) \ + int count; \ +{ \ + CARD##bpp *data = (CARD##bpp *)tightBeforeBuf; \ + CARD##bpp c0, c1, ci; \ + int i, n0, n1, ni; \ + \ + c0 = data[0]; \ + for (i = 1; i < count && data[i] == c0; i++); \ + if (i == count) { \ + paletteNumColors = 1; /* Solid rectangle */ \ + return; \ + } \ + \ + if (paletteMaxColors < 2) { \ + paletteNumColors = 0; /* Full-color encoding preferred */ \ + return; \ + } \ + \ + n0 = i; \ + c1 = data[i]; \ + n1 = 0; \ + for (i++; i < count; i++) { \ + ci = data[i]; \ + if (ci == c0) { \ + n0++; \ + } else if (ci == c1) { \ + n1++; \ + } else \ + break; \ + } \ + if (i == count) { \ + if (n0 > n1) { \ + monoBackground = (CARD32)c0; \ + monoForeground = (CARD32)c1; \ + } else { \ + monoBackground = (CARD32)c1; \ + monoForeground = (CARD32)c0; \ + } \ + paletteNumColors = 2; /* Two colors */ \ + return; \ + } \ + \ + PaletteReset(); \ + PaletteInsert (c0, (CARD32)n0, bpp); \ + PaletteInsert (c1, (CARD32)n1, bpp); \ + \ + ni = 1; \ + for (i++; i < count; i++) { \ + if (data[i] == ci) { \ + ni++; \ + } else { \ + if (!PaletteInsert (ci, (CARD32)ni, bpp)) \ + return; \ + ci = data[i]; \ + ni = 1; \ + } \ + } \ + PaletteInsert (ci, (CARD32)ni, bpp); \ +} + +DEFINE_FILL_PALETTE_FUNCTION(16) +DEFINE_FILL_PALETTE_FUNCTION(32) + + +/* + * Functions to operate with palette structures. + */ + +#define HASH_FUNC16(rgb) ((int)(((rgb >> 8) + rgb) & 0xFF)) +#define HASH_FUNC32(rgb) ((int)(((rgb >> 16) + (rgb >> 8)) & 0xFF)) + +static void +PaletteReset(void) +{ + paletteNumColors = 0; + memset(palette.hash, 0, 256 * sizeof(COLOR_LIST *)); +} + +static int +PaletteInsert(rgb, numPixels, bpp) + CARD32 rgb; + int numPixels; + int bpp; +{ + COLOR_LIST *pnode; + COLOR_LIST *prev_pnode = NULL; + int hash_key, idx, new_idx, count; + + hash_key = (bpp == 16) ? HASH_FUNC16(rgb) : HASH_FUNC32(rgb); + + pnode = palette.hash[hash_key]; + + while (pnode != NULL) { + if (pnode->rgb == rgb) { + /* Such palette entry already exists. */ + new_idx = idx = pnode->idx; + count = palette.entry[idx].numPixels + numPixels; + if (new_idx && palette.entry[new_idx-1].numPixels < count) { + do { + palette.entry[new_idx] = palette.entry[new_idx-1]; + palette.entry[new_idx].listNode->idx = new_idx; + new_idx--; + } + while (new_idx && palette.entry[new_idx-1].numPixels < count); + palette.entry[new_idx].listNode = pnode; + pnode->idx = new_idx; + } + palette.entry[new_idx].numPixels = count; + return paletteNumColors; + } + prev_pnode = pnode; + pnode = pnode->next; + } + + /* Check if palette is full. */ + if (paletteNumColors == 256 || paletteNumColors == paletteMaxColors) { + paletteNumColors = 0; + return 0; + } + + /* Move palette entries with lesser pixel counts. */ + for ( idx = paletteNumColors; + idx > 0 && palette.entry[idx-1].numPixels < numPixels; + idx-- ) { + palette.entry[idx] = palette.entry[idx-1]; + palette.entry[idx].listNode->idx = idx; + } + + /* Add new palette entry into the freed slot. */ + pnode = &palette.list[paletteNumColors]; + if (prev_pnode != NULL) { + prev_pnode->next = pnode; + } else { + palette.hash[hash_key] = pnode; + } + pnode->next = NULL; + pnode->idx = idx; + pnode->rgb = rgb; + palette.entry[idx].listNode = pnode; + palette.entry[idx].numPixels = numPixels; + + return (++paletteNumColors); +} + + +/* + * Converting 32-bit color samples into 24-bit colors. + * Should be called only when redMax, greenMax and blueMax are 255. + * Color components assumed to be byte-aligned. + */ + +static void Pack24(cl, buf, fmt, count) + rfbClientPtr cl; + char *buf; + rfbPixelFormat *fmt; + int count; +{ + CARD32 *buf32; + CARD32 pix; + int r_shift, g_shift, b_shift; + + buf32 = (CARD32 *)buf; + + if (!cl->screen->rfbServerFormat.bigEndian == !fmt->bigEndian) { + r_shift = fmt->redShift; + g_shift = fmt->greenShift; + b_shift = fmt->blueShift; + } else { + r_shift = 24 - fmt->redShift; + g_shift = 24 - fmt->greenShift; + b_shift = 24 - fmt->blueShift; + } + + while (count--) { + pix = *buf32++; + *buf++ = (char)(pix >> r_shift); + *buf++ = (char)(pix >> g_shift); + *buf++ = (char)(pix >> b_shift); + } +} + + +/* + * Converting truecolor samples into palette indices. + */ + +#define DEFINE_IDX_ENCODE_FUNCTION(bpp) \ + \ +static void \ +EncodeIndexedRect##bpp(buf, count) \ + CARD8 *buf; \ + int count; \ +{ \ + COLOR_LIST *pnode; \ + CARD##bpp *src; \ + CARD##bpp rgb; \ + int rep = 0; \ + \ + src = (CARD##bpp *) buf; \ + \ + while (count--) { \ + rgb = *src++; \ + while (count && *src == rgb) { \ + rep++, src++, count--; \ + } \ + pnode = palette.hash[HASH_FUNC##bpp(rgb)]; \ + while (pnode != NULL) { \ + if ((CARD##bpp)pnode->rgb == rgb) { \ + *buf++ = (CARD8)pnode->idx; \ + while (rep) { \ + *buf++ = (CARD8)pnode->idx; \ + rep--; \ + } \ + break; \ + } \ + pnode = pnode->next; \ + } \ + } \ +} + +DEFINE_IDX_ENCODE_FUNCTION(16) +DEFINE_IDX_ENCODE_FUNCTION(32) + +#define DEFINE_MONO_ENCODE_FUNCTION(bpp) \ + \ +static void \ +EncodeMonoRect##bpp(buf, w, h) \ + CARD8 *buf; \ + int w, h; \ +{ \ + CARD##bpp *ptr; \ + CARD##bpp bg; \ + unsigned int value, mask; \ + int aligned_width; \ + int x, y, bg_bits; \ + \ + ptr = (CARD##bpp *) buf; \ + bg = (CARD##bpp) monoBackground; \ + aligned_width = w - w % 8; \ + \ + for (y = 0; y < h; y++) { \ + for (x = 0; x < aligned_width; x += 8) { \ + for (bg_bits = 0; bg_bits < 8; bg_bits++) { \ + if (*ptr++ != bg) \ + break; \ + } \ + if (bg_bits == 8) { \ + *buf++ = 0; \ + continue; \ + } \ + mask = 0x80 >> bg_bits; \ + value = mask; \ + for (bg_bits++; bg_bits < 8; bg_bits++) { \ + mask >>= 1; \ + if (*ptr++ != bg) { \ + value |= mask; \ + } \ + } \ + *buf++ = (CARD8)value; \ + } \ + \ + mask = 0x80; \ + value = 0; \ + if (x >= w) \ + continue; \ + \ + for (; x < w; x++) { \ + if (*ptr++ != bg) { \ + value |= mask; \ + } \ + mask >>= 1; \ + } \ + *buf++ = (CARD8)value; \ + } \ +} + +DEFINE_MONO_ENCODE_FUNCTION(8) +DEFINE_MONO_ENCODE_FUNCTION(16) +DEFINE_MONO_ENCODE_FUNCTION(32) + + +/* + * ``Gradient'' filter for 24-bit color samples. + * Should be called only when redMax, greenMax and blueMax are 255. + * Color components assumed to be byte-aligned. + */ + +static void +FilterGradient24(cl, buf, fmt, w, h) + rfbClientPtr cl; + char *buf; + rfbPixelFormat *fmt; + int w, h; +{ + CARD32 *buf32; + CARD32 pix32; + int *prevRowPtr; + int shiftBits[3]; + int pixHere[3], pixUpper[3], pixLeft[3], pixUpperLeft[3]; + int prediction; + int x, y, c; + + buf32 = (CARD32 *)buf; + memset (prevRowBuf, 0, w * 3 * sizeof(int)); + + if (!cl->screen->rfbServerFormat.bigEndian == !fmt->bigEndian) { + shiftBits[0] = fmt->redShift; + shiftBits[1] = fmt->greenShift; + shiftBits[2] = fmt->blueShift; + } else { + shiftBits[0] = 24 - fmt->redShift; + shiftBits[1] = 24 - fmt->greenShift; + shiftBits[2] = 24 - fmt->blueShift; + } + + for (y = 0; y < h; y++) { + for (c = 0; c < 3; c++) { + pixUpper[c] = 0; + pixHere[c] = 0; + } + prevRowPtr = prevRowBuf; + for (x = 0; x < w; x++) { + pix32 = *buf32++; + for (c = 0; c < 3; c++) { + pixUpperLeft[c] = pixUpper[c]; + pixLeft[c] = pixHere[c]; + pixUpper[c] = *prevRowPtr; + pixHere[c] = (int)(pix32 >> shiftBits[c] & 0xFF); + *prevRowPtr++ = pixHere[c]; + + prediction = pixLeft[c] + pixUpper[c] - pixUpperLeft[c]; + if (prediction < 0) { + prediction = 0; + } else if (prediction > 0xFF) { + prediction = 0xFF; + } + *buf++ = (char)(pixHere[c] - prediction); + } + } + } +} + + +/* + * ``Gradient'' filter for other color depths. + */ + +#define DEFINE_GRADIENT_FILTER_FUNCTION(bpp) \ + \ +static void \ +FilterGradient##bpp(cl, buf, fmt, w, h) \ + rfbClientPtr cl; \ + CARD##bpp *buf; \ + rfbPixelFormat *fmt; \ + int w, h; \ +{ \ + CARD##bpp pix, diff; \ + Bool endianMismatch; \ + int *prevRowPtr; \ + int maxColor[3], shiftBits[3]; \ + int pixHere[3], pixUpper[3], pixLeft[3], pixUpperLeft[3]; \ + int prediction; \ + int x, y, c; \ + \ + memset (prevRowBuf, 0, w * 3 * sizeof(int)); \ + \ + endianMismatch = (!cl->screen->rfbServerFormat.bigEndian != !fmt->bigEndian); \ + \ + maxColor[0] = fmt->redMax; \ + maxColor[1] = fmt->greenMax; \ + maxColor[2] = fmt->blueMax; \ + shiftBits[0] = fmt->redShift; \ + shiftBits[1] = fmt->greenShift; \ + shiftBits[2] = fmt->blueShift; \ + \ + for (y = 0; y < h; y++) { \ + for (c = 0; c < 3; c++) { \ + pixUpper[c] = 0; \ + pixHere[c] = 0; \ + } \ + prevRowPtr = prevRowBuf; \ + for (x = 0; x < w; x++) { \ + pix = *buf; \ + if (endianMismatch) { \ + pix = Swap##bpp(pix); \ + } \ + diff = 0; \ + for (c = 0; c < 3; c++) { \ + pixUpperLeft[c] = pixUpper[c]; \ + pixLeft[c] = pixHere[c]; \ + pixUpper[c] = *prevRowPtr; \ + pixHere[c] = (int)(pix >> shiftBits[c] & maxColor[c]); \ + *prevRowPtr++ = pixHere[c]; \ + \ + prediction = pixLeft[c] + pixUpper[c] - pixUpperLeft[c]; \ + if (prediction < 0) { \ + prediction = 0; \ + } else if (prediction > maxColor[c]) { \ + prediction = maxColor[c]; \ + } \ + diff |= ((pixHere[c] - prediction) & maxColor[c]) \ + << shiftBits[c]; \ + } \ + if (endianMismatch) { \ + diff = Swap##bpp(diff); \ + } \ + *buf++ = diff; \ + } \ + } \ +} + +DEFINE_GRADIENT_FILTER_FUNCTION(16) +DEFINE_GRADIENT_FILTER_FUNCTION(32) + + +/* + * Code to guess if given rectangle is suitable for smooth image + * compression (by applying "gradient" filter or JPEG coder). + */ + +#define JPEG_MIN_RECT_SIZE 4096 + +#define DETECT_SUBROW_WIDTH 7 +#define DETECT_MIN_WIDTH 8 +#define DETECT_MIN_HEIGHT 8 + +static int +DetectSmoothImage (cl, fmt, w, h) + rfbClientPtr cl; + rfbPixelFormat *fmt; + int w, h; +{ + unsigned long avgError; + + if ( cl->screen->rfbServerFormat.bitsPerPixel == 8 || fmt->bitsPerPixel == 8 || + w < DETECT_MIN_WIDTH || h < DETECT_MIN_HEIGHT ) { + return 0; + } + + if (qualityLevel != -1) { + if (w * h < JPEG_MIN_RECT_SIZE) { + return 0; + } + } else { + if ( rfbTightDisableGradient || + w * h < tightConf[compressLevel].gradientMinRectSize ) { + return 0; + } + } + + if (fmt->bitsPerPixel == 32) { + if (usePixelFormat24) { + avgError = DetectSmoothImage24(cl, fmt, w, h); + if (qualityLevel != -1) { + return (avgError < tightConf[qualityLevel].jpegThreshold24); + } + return (avgError < tightConf[compressLevel].gradientThreshold24); + } else { + avgError = DetectSmoothImage32(cl, fmt, w, h); + } + } else { + avgError = DetectSmoothImage16(cl, fmt, w, h); + } + if (qualityLevel != -1) { + return (avgError < tightConf[qualityLevel].jpegThreshold); + } + return (avgError < tightConf[compressLevel].gradientThreshold); +} + +static unsigned long +DetectSmoothImage24 (cl, fmt, w, h) + rfbClientPtr cl; + rfbPixelFormat *fmt; + int w, h; +{ + int off; + int x, y, d, dx, c; + int diffStat[256]; + int pixelCount = 0; + int pix, left[3]; + unsigned long avgError; + + /* If client is big-endian, color samples begin from the second + byte (offset 1) of a 32-bit pixel value. */ + off = (fmt->bigEndian != 0); + + memset(diffStat, 0, 256*sizeof(int)); + + y = 0, x = 0; + while (y < h && x < w) { + for (d = 0; d < h - y && d < w - x - DETECT_SUBROW_WIDTH; d++) { + for (c = 0; c < 3; c++) { + left[c] = (int)tightBeforeBuf[((y+d)*w+x+d)*4+off+c] & 0xFF; + } + for (dx = 1; dx <= DETECT_SUBROW_WIDTH; dx++) { + for (c = 0; c < 3; c++) { + pix = (int)tightBeforeBuf[((y+d)*w+x+d+dx)*4+off+c] & 0xFF; + diffStat[abs(pix - left[c])]++; + left[c] = pix; + } + pixelCount++; + } + } + if (w > h) { + x += h; + y = 0; + } else { + x = 0; + y += w; + } + } + + if (diffStat[0] * 33 / pixelCount >= 95) + return 0; + + avgError = 0; + for (c = 1; c < 8; c++) { + avgError += (unsigned long)diffStat[c] * (unsigned long)(c * c); + if (diffStat[c] == 0 || diffStat[c] > diffStat[c-1] * 2) + return 0; + } + for (; c < 256; c++) { + avgError += (unsigned long)diffStat[c] * (unsigned long)(c * c); + } + avgError /= (pixelCount * 3 - diffStat[0]); + + return avgError; +} + +#define DEFINE_DETECT_FUNCTION(bpp) \ + \ +static unsigned long \ +DetectSmoothImage##bpp (cl, fmt, w, h) \ + rfbClientPtr cl; \ + rfbPixelFormat *fmt; \ + int w, h; \ +{ \ + Bool endianMismatch; \ + CARD##bpp pix; \ + int maxColor[3], shiftBits[3]; \ + int x, y, d, dx, c; \ + int diffStat[256]; \ + int pixelCount = 0; \ + int sample, sum, left[3]; \ + unsigned long avgError; \ + \ + endianMismatch = (!cl->screen->rfbServerFormat.bigEndian != !fmt->bigEndian); \ + \ + maxColor[0] = fmt->redMax; \ + maxColor[1] = fmt->greenMax; \ + maxColor[2] = fmt->blueMax; \ + shiftBits[0] = fmt->redShift; \ + shiftBits[1] = fmt->greenShift; \ + shiftBits[2] = fmt->blueShift; \ + \ + memset(diffStat, 0, 256*sizeof(int)); \ + \ + y = 0, x = 0; \ + while (y < h && x < w) { \ + for (d = 0; d < h - y && d < w - x - DETECT_SUBROW_WIDTH; d++) { \ + pix = ((CARD##bpp *)tightBeforeBuf)[(y+d)*w+x+d]; \ + if (endianMismatch) { \ + pix = Swap##bpp(pix); \ + } \ + for (c = 0; c < 3; c++) { \ + left[c] = (int)(pix >> shiftBits[c] & maxColor[c]); \ + } \ + for (dx = 1; dx <= DETECT_SUBROW_WIDTH; dx++) { \ + pix = ((CARD##bpp *)tightBeforeBuf)[(y+d)*w+x+d+dx]; \ + if (endianMismatch) { \ + pix = Swap##bpp(pix); \ + } \ + sum = 0; \ + for (c = 0; c < 3; c++) { \ + sample = (int)(pix >> shiftBits[c] & maxColor[c]); \ + sum += abs(sample - left[c]); \ + left[c] = sample; \ + } \ + if (sum > 255) \ + sum = 255; \ + diffStat[sum]++; \ + pixelCount++; \ + } \ + } \ + if (w > h) { \ + x += h; \ + y = 0; \ + } else { \ + x = 0; \ + y += w; \ + } \ + } \ + \ + if ((diffStat[0] + diffStat[1]) * 100 / pixelCount >= 90) \ + return 0; \ + \ + avgError = 0; \ + for (c = 1; c < 8; c++) { \ + avgError += (unsigned long)diffStat[c] * (unsigned long)(c * c); \ + if (diffStat[c] == 0 || diffStat[c] > diffStat[c-1] * 2) \ + return 0; \ + } \ + for (; c < 256; c++) { \ + avgError += (unsigned long)diffStat[c] * (unsigned long)(c * c); \ + } \ + avgError /= (pixelCount - diffStat[0]); \ + \ + return avgError; \ +} + +DEFINE_DETECT_FUNCTION(16) +DEFINE_DETECT_FUNCTION(32) + + +/* + * JPEG compression stuff. + */ + +static struct jpeg_destination_mgr jpegDstManager; +static Bool jpegError; +static int jpegDstDataLen; + +static Bool +SendJpegRect(cl, x, y, w, h, quality) + rfbClientPtr cl; + int x, y, w, h; + int quality; +{ + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + CARD8 *srcBuf; + JSAMPROW rowPointer[1]; + int dy; + + if (cl->screen->rfbServerFormat.bitsPerPixel == 8) + return SendFullColorRect(cl, w, h); + + srcBuf = (CARD8 *)xalloc(w * 3); + if (srcBuf == NULL) { + return SendFullColorRect(cl, w, h); + } + 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, quality, TRUE); + + JpegSetDstManager (&cinfo); + + jpeg_start_compress(&cinfo, TRUE); + + for (dy = 0; dy < h; dy++) { + PrepareRowForJpeg(cl, srcBuf, x, y + dy, w); + jpeg_write_scanlines(&cinfo, rowPointer, 1); + if (jpegError) + break; + } + + if (!jpegError) + jpeg_finish_compress(&cinfo); + + jpeg_destroy_compress(&cinfo); + free(srcBuf); + + if (jpegError) + return SendFullColorRect(cl, w, h); + + if (cl->ublen + TIGHT_MIN_TO_COMPRESS + 1 > UPDATE_BUF_SIZE) { + if (!rfbSendUpdateBuf(cl)) + return FALSE; + } + + cl->updateBuf[cl->ublen++] = (char)(rfbTightJpeg << 4); + cl->rfbBytesSent[rfbEncodingTight]++; + + return SendCompressedData(cl, jpegDstDataLen); +} + +static void +PrepareRowForJpeg(cl, dst, x, y, count) + rfbClientPtr cl; + CARD8 *dst; + int x, y, count; +{ + if (cl->screen->rfbServerFormat.bitsPerPixel == 32) { + if ( cl->screen->rfbServerFormat.redMax == 0xFF && + cl->screen->rfbServerFormat.greenMax == 0xFF && + cl->screen->rfbServerFormat.blueMax == 0xFF ) { + PrepareRowForJpeg24(cl, dst, x, y, count); + } else { + PrepareRowForJpeg32(cl, dst, x, y, count); + } + } else { + /* 16 bpp assumed. */ + PrepareRowForJpeg16(cl, dst, x, y, count); + } +} + +static void +PrepareRowForJpeg24(cl, dst, x, y, count) + rfbClientPtr cl; + CARD8 *dst; + int x, y, count; +{ + CARD32 *fbptr; + CARD32 pix; + + fbptr = (CARD32 *) + &cl->screen->frameBuffer[y * cl->screen->paddedWidthInBytes + x * 4]; + + while (count--) { + pix = *fbptr++; + *dst++ = (CARD8)(pix >> cl->screen->rfbServerFormat.redShift); + *dst++ = (CARD8)(pix >> cl->screen->rfbServerFormat.greenShift); + *dst++ = (CARD8)(pix >> cl->screen->rfbServerFormat.blueShift); + } +} + +#define DEFINE_JPEG_GET_ROW_FUNCTION(bpp) \ + \ +static void \ +PrepareRowForJpeg##bpp(cl, dst, x, y, count) \ + rfbClientPtr cl; \ + CARD8 *dst; \ + int x, y, count; \ +{ \ + CARD##bpp *fbptr; \ + CARD##bpp pix; \ + int inRed, inGreen, inBlue; \ + \ + fbptr = (CARD##bpp *) \ + &cl->screen->frameBuffer[y * cl->screen->paddedWidthInBytes + \ + x * (bpp / 8)]; \ + \ + while (count--) { \ + pix = *fbptr++; \ + \ + inRed = (int) \ + (pix >> cl->screen->rfbServerFormat.redShift & cl->screen->rfbServerFormat.redMax); \ + inGreen = (int) \ + (pix >> cl->screen->rfbServerFormat.greenShift & cl->screen->rfbServerFormat.greenMax); \ + inBlue = (int) \ + (pix >> cl->screen->rfbServerFormat.blueShift & cl->screen->rfbServerFormat.blueMax); \ + \ + *dst++ = (CARD8)((inRed * 255 + cl->screen->rfbServerFormat.redMax / 2) / \ + cl->screen->rfbServerFormat.redMax); \ + *dst++ = (CARD8)((inGreen * 255 + cl->screen->rfbServerFormat.greenMax / 2) / \ + cl->screen->rfbServerFormat.greenMax); \ + *dst++ = (CARD8)((inBlue * 255 + cl->screen->rfbServerFormat.blueMax / 2) / \ + cl->screen->rfbServerFormat.blueMax); \ + } \ +} + +DEFINE_JPEG_GET_ROW_FUNCTION(16) +DEFINE_JPEG_GET_ROW_FUNCTION(32) + +/* + * Destination manager implementation for JPEG library. + */ + +static void +JpegInitDestination(j_compress_ptr cinfo) +{ + jpegError = FALSE; + jpegDstManager.next_output_byte = (JOCTET *)tightAfterBuf; + jpegDstManager.free_in_buffer = (size_t)tightAfterBufSize; +} + +static boolean +JpegEmptyOutputBuffer(j_compress_ptr cinfo) +{ + jpegError = TRUE; + jpegDstManager.next_output_byte = (JOCTET *)tightAfterBuf; + jpegDstManager.free_in_buffer = (size_t)tightAfterBufSize; + + return TRUE; +} + +static void +JpegTermDestination(j_compress_ptr cinfo) +{ + jpegDstDataLen = tightAfterBufSize - jpegDstManager.free_in_buffer; +} + +static 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/translate.c b/translate.c new file mode 100644 index 0000000..82de89e --- /dev/null +++ b/translate.c @@ -0,0 +1,400 @@ +/* + * translate.c - translate between different pixel formats + */ + +/* + * OSXvnc Copyright (C) 2001 Dan McGuirk . + * Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge. + * All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include +#include +#include "rfb.h" + +static void PrintPixelFormat(rfbPixelFormat *pf); +static Bool rfbSetClientColourMapBGR233(); + +Bool rfbEconomicTranslate = FALSE; + +/* + * Some standard pixel formats. + */ + +static const rfbPixelFormat BGR233Format = { + 8, 8, 0, 1, 7, 7, 3, 0, 3, 6 +}; + + +/* + * Macro to compare pixel formats. + */ + +#define PF_EQ(x,y) \ + ((x.bitsPerPixel == y.bitsPerPixel) && \ + (x.depth == y.depth) && \ + ((x.bigEndian == y.bigEndian) || (x.bitsPerPixel == 8)) && \ + (x.trueColour == y.trueColour) && \ + (!x.trueColour || ((x.redMax == y.redMax) && \ + (x.greenMax == y.greenMax) && \ + (x.blueMax == y.blueMax) && \ + (x.redShift == y.redShift) && \ + (x.greenShift == y.greenShift) && \ + (x.blueShift == y.blueShift)))) + +#define CONCAT2(a,b) a##b +#define CONCAT2E(a,b) CONCAT2(a,b) +#define CONCAT4(a,b,c,d) a##b##c##d +#define CONCAT4E(a,b,c,d) CONCAT4(a,b,c,d) + +#define OUT 8 +#include "tableinittctemplate.c" +#define IN 8 +#include "tabletranstemplate.c" +#undef IN +#define IN 16 +#include "tabletranstemplate.c" +#undef IN +#define IN 32 +#include "tabletranstemplate.c" +#undef IN +#undef OUT + +#define OUT 16 +#include "tableinittctemplate.c" +#define IN 8 +#include "tabletranstemplate.c" +#undef IN +#define IN 16 +#include "tabletranstemplate.c" +#undef IN +#define IN 32 +#include "tabletranstemplate.c" +#undef IN +#undef OUT + +#define OUT 32 +#include "tableinittctemplate.c" +#define IN 8 +#include "tabletranstemplate.c" +#undef IN +#define IN 16 +#include "tabletranstemplate.c" +#undef IN +#define IN 32 +#include "tabletranstemplate.c" +#undef IN +#undef OUT + +typedef void (*rfbInitTableFnType)(char **table, rfbPixelFormat *in, + rfbPixelFormat *out); + +rfbInitTableFnType rfbInitTrueColourSingleTableFns[3] = { + rfbInitTrueColourSingleTable8, + rfbInitTrueColourSingleTable16, + rfbInitTrueColourSingleTable32 +}; + +rfbInitTableFnType rfbInitTrueColourRGBTablesFns[3] = { + rfbInitTrueColourRGBTables8, + rfbInitTrueColourRGBTables16, + rfbInitTrueColourRGBTables32 +}; + +rfbTranslateFnType rfbTranslateWithSingleTableFns[3][3] = { + { rfbTranslateWithSingleTable8to8, + rfbTranslateWithSingleTable8to16, + rfbTranslateWithSingleTable8to32 }, + { rfbTranslateWithSingleTable16to8, + rfbTranslateWithSingleTable16to16, + rfbTranslateWithSingleTable16to32 }, + { rfbTranslateWithSingleTable32to8, + rfbTranslateWithSingleTable32to16, + rfbTranslateWithSingleTable32to32 } +}; + +rfbTranslateFnType rfbTranslateWithRGBTablesFns[3][3] = { + { rfbTranslateWithRGBTables8to8, + rfbTranslateWithRGBTables8to16, + rfbTranslateWithRGBTables8to32 }, + { rfbTranslateWithRGBTables16to8, + rfbTranslateWithRGBTables16to16, + rfbTranslateWithRGBTables16to32 }, + { rfbTranslateWithRGBTables32to8, + rfbTranslateWithRGBTables32to16, + rfbTranslateWithRGBTables32to32 } +}; + + + +/* + * rfbTranslateNone is used when no translation is required. + */ + +void +rfbTranslateNone(char *table, rfbPixelFormat *in, rfbPixelFormat *out, + char *iptr, char *optr, int bytesBetweenInputLines, + int width, int height) +{ + int bytesPerOutputLine = width * (out->bitsPerPixel / 8); + + while (height > 0) { + memcpy(optr, iptr, bytesPerOutputLine); + iptr += bytesBetweenInputLines; + optr += bytesPerOutputLine; + height--; + } +} + + +/* + * rfbSetTranslateFunction sets the translation function. + */ + +Bool +rfbSetTranslateFunction(cl) + rfbClientPtr cl; +{ + rfbLog("Pixel format for client %s:\n",cl->host); + PrintPixelFormat(&cl->format); + + /* + * Check that bits per pixel values are valid + */ + + if ((cl->screen->rfbServerFormat.bitsPerPixel != 8) && + (cl->screen->rfbServerFormat.bitsPerPixel != 16) && + (cl->screen->rfbServerFormat.bitsPerPixel != 32)) + { + rfbLog("%s: server bits per pixel not 8, 16 or 32\n", + "rfbSetTranslateFunction"); + rfbCloseClient(cl); + return FALSE; + } + + if ((cl->format.bitsPerPixel != 8) && + (cl->format.bitsPerPixel != 16) && + (cl->format.bitsPerPixel != 32)) + { + rfbLog("%s: client bits per pixel not 8, 16 or 32\n", + "rfbSetTranslateFunction"); + rfbCloseClient(cl); + return FALSE; + } + + if (!cl->format.trueColour && (cl->format.bitsPerPixel != 8)) { + rfbLog("rfbSetTranslateFunction: client has colour map " + "but %d-bit - can only cope with 8-bit colour maps\n", + cl->format.bitsPerPixel); + rfbCloseClient(cl); + return FALSE; + } + + /* + * bpp is valid, now work out how to translate + */ + + if (!cl->format.trueColour) { + /* + * truecolour -> colour map + * + * Set client's colour map to BGR233, then effectively it's + * truecolour as well + */ + + if (!rfbSetClientColourMapBGR233(cl)) + return FALSE; + + cl->format = BGR233Format; + } + + /* truecolour -> truecolour */ + + if (PF_EQ(cl->format,cl->screen->rfbServerFormat)) { + + /* client & server the same */ + + rfbLog("no translation needed\n"); + cl->translateFn = rfbTranslateNone; + return TRUE; + } + + if ((cl->screen->rfbServerFormat.bitsPerPixel < 16) || + (!rfbEconomicTranslate && (cl->screen->rfbServerFormat.bitsPerPixel == 16))) { + + /* we can use a single lookup table for <= 16 bpp */ + + cl->translateFn = rfbTranslateWithSingleTableFns + [cl->screen->rfbServerFormat.bitsPerPixel / 16] + [cl->format.bitsPerPixel / 16]; + + (*rfbInitTrueColourSingleTableFns + [cl->format.bitsPerPixel / 16]) (&cl->translateLookupTable, + &(cl->screen->rfbServerFormat), &cl->format); + + } else { + + /* otherwise we use three separate tables for red, green and blue */ + + cl->translateFn = rfbTranslateWithRGBTablesFns + [cl->screen->rfbServerFormat.bitsPerPixel / 16] + [cl->format.bitsPerPixel / 16]; + + (*rfbInitTrueColourRGBTablesFns + [cl->format.bitsPerPixel / 16]) (&cl->translateLookupTable, + &(cl->screen->rfbServerFormat), &cl->format); + } + + return TRUE; +} + + + +/* + * rfbSetClientColourMapBGR233 sets the client's colour map so that it's + * just like an 8-bit BGR233 true colour client. + */ + +static Bool +rfbSetClientColourMapBGR233(cl) + rfbClientPtr cl; +{ + char buf[sz_rfbSetColourMapEntriesMsg + 256 * 3 * 2]; + rfbSetColourMapEntriesMsg *scme = (rfbSetColourMapEntriesMsg *)buf; + CARD16 *rgb = (CARD16 *)(&buf[sz_rfbSetColourMapEntriesMsg]); + int i, len; + int r, g, b; + + if (cl->format.bitsPerPixel != 8) { + rfbLog("%s: client not 8 bits per pixel\n", + "rfbSetClientColourMapBGR233"); + rfbCloseClient(cl); + return FALSE; + } + + scme->type = rfbSetColourMapEntries; + + scme->firstColour = Swap16IfLE(0); + scme->nColours = Swap16IfLE(256); + + len = sz_rfbSetColourMapEntriesMsg; + + i = 0; + + for (b = 0; b < 4; b++) { + for (g = 0; g < 8; g++) { + for (r = 0; r < 8; r++) { + rgb[i++] = Swap16IfLE(r * 65535 / 7); + rgb[i++] = Swap16IfLE(g * 65535 / 7); + rgb[i++] = Swap16IfLE(b * 65535 / 3); + } + } + } + + len += 256 * 3 * 2; + + if (WriteExact(cl, buf, len) < 0) { + rfbLogPerror("rfbSetClientColourMapBGR233: write"); + rfbCloseClient(cl); + return FALSE; + } + return TRUE; +} + +#ifdef NOT_YET +/* + * rfbSetClientColourMap is called to set the client's colour map. If the + * client is a true colour client, we simply update our own translation table + * and mark the whole screen as having been modified. + */ + +Bool +rfbSetClientColourMap(cl, firstColour, nColours) + rfbClientPtr cl; + int firstColour; + int nColours; +{ + EntryPtr pent; + int i, r, g, b; + BoxRec box; + + if (nColours == 0) { + nColours = rfbInstalledColormap->pVisual->ColormapEntries; + } + + if (rfbServerFormat.trueColour || !cl->readyForSetColourMapEntries) { + return TRUE; + } + + if (cl->format.trueColour) { + (*rfbInitColourMapSingleTableFns + [cl->format.bitsPerPixel / 16]) (&cl->translateLookupTable, + &rfbServerFormat, &cl->format); + + REGION_UNINIT(pScreen,&cl->modifiedRegion); + box.x1 = box.y1 = 0; + box.x2 = rfbScreen.width; + box.y2 = rfbScreen.height; + REGION_INIT(pScreen,&cl->modifiedRegion,&box,0); + + return TRUE; + } + + return rfbSendSetColourMapEntries(cl, firstColour, nColours); +} + + +/* + * rfbSetClientColourMaps sets the colour map for each RFB client. + */ + +void +rfbSetClientColourMaps(rfbScreen, firstColour, nColours) + rfbScreenInfoPtr rfbScreen; + int firstColour; + int nColours; +{ + rfbClientPtr cl, nextCl; + + for (cl = rfbScreen->rfbClientHead; cl; cl = nextCl) { + nextCl = cl->next; + rfbSetClientColourMap(cl, firstColour, nColours); + } +} +#endif + +static void +PrintPixelFormat(pf) + rfbPixelFormat *pf; +{ + if (pf->bitsPerPixel == 1) { + rfbLog(" 1 bpp, %s sig bit in each byte is leftmost on the screen.\n", + (pf->bigEndian ? "most" : "least")); + } else { + rfbLog(" %d bpp, depth %d%s\n",pf->bitsPerPixel,pf->depth, + ((pf->bitsPerPixel == 8) ? "" + : (pf->bigEndian ? ", big endian" : ", little endian"))); + if (pf->trueColour) { + rfbLog(" true colour: max r %d g %d b %d, shift r %d g %d b %d\n", + pf->redMax, pf->greenMax, pf->blueMax, + pf->redShift, pf->greenShift, pf->blueShift); + } else { + rfbLog(" uses a colour map (not true colour).\n"); + } + } +} diff --git a/xalloc.c b/xalloc.c new file mode 100644 index 0000000..acccb67 --- /dev/null +++ b/xalloc.c @@ -0,0 +1,205 @@ +/* XALLOC -- X's internal memory allocator. Why does it return unsigned + * long * instead of the more common char *? Well, if you read K&R you'll + * see they say that alloc must return a pointer "suitable for conversion" + * to whatever type you really want. In a full-blown generic allocator + * there's no way to solve the alignment problems without potentially + * wasting lots of space. But we have a more limited problem. We know + * we're only ever returning pointers to structures which will have to + * be long word aligned. So we are making a stronger guarantee. It might + * have made sense to make Xalloc return char * to conform with people's + * expectations of malloc, but this makes lint happier. + */ + +#ifdef WIN32 +#include +#endif +#include "Xos.h" +#include +#include "misc.h" +#include "X.h" +#include "input.h" +#include "opaque.h" +#ifdef X_POSIX_C_SOURCE +#define _POSIX_C_SOURCE X_POSIX_C_SOURCE +#include +#undef _POSIX_C_SOURCE +#else +#if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE) +#include +#else +#define _POSIX_SOURCE +#include +#undef _POSIX_SOURCE +#endif +#endif +#if !defined(SYSV) && !defined(AMOEBA) && !defined(_MINIX) && !defined(WIN32) && !defined(Lynx) +#include +#endif +#include +#include +#include /* for isspace */ +#if NeedVarargsPrototypes +#include +#endif +#ifdef __sgi__ +#undef abs +#endif +#include + +#ifndef INTERNAL_MALLOC + +Bool Must_have_memory = FALSE; + +unsigned long * +Xalloc (amount) + unsigned long amount; +{ +#if !defined(__STDC__) && !defined(AMOEBA) + char *malloc(); +#endif + register pointer ptr; + + if ((long)amount <= 0) { + return (unsigned long *)NULL; + } + /* aligned extra on long word boundary */ + amount = (amount + (sizeof(long) - 1)) & ~(sizeof(long) - 1); +#ifdef MEMBUG + if (!Must_have_memory && Memory_fail && + ((random() % MEM_FAIL_SCALE) < Memory_fail)) + return (unsigned long *)NULL; +#endif + if ((ptr = (pointer)malloc(amount))) { + return (unsigned long *)ptr; + } + if (Must_have_memory) + FatalError("Out of memory"); + return (unsigned long *)NULL; +} + +/***************** + * XNFalloc + * "no failure" realloc, alternate interface to Xalloc w/o Must_have_memory + *****************/ + +unsigned long * +XNFalloc (amount) + unsigned long amount; +{ +#if !defined(__STDC__) && !defined(AMOEBA) + char *malloc(); +#endif + register pointer ptr; + + if ((long)amount <= 0) + { + return (unsigned long *)NULL; + } + /* aligned extra on long word boundary */ + amount = (amount + (sizeof(long) - 1)) & ~(sizeof(long) - 1); + ptr = (pointer)malloc(amount); + if (!ptr) + { + FatalError("Out of memory"); + } + return ((unsigned long *)ptr); +} + +/***************** + * Xcalloc + *****************/ + +unsigned long * +Xcalloc (amount) + unsigned long amount; +{ + unsigned long *ret; + + ret = Xalloc (amount); + if (ret) + bzero ((char *) ret, (int) amount); + return ret; +} + +/***************** + * Xrealloc + *****************/ + +unsigned long * +Xrealloc (ptr, amount) + register pointer ptr; + unsigned long amount; +{ +#if !defined(__STDC__) && !defined(AMOEBA) + char *malloc(); + char *realloc(); +#endif + +#ifdef MEMBUG + if (!Must_have_memory && Memory_fail && + ((random() % MEM_FAIL_SCALE) < Memory_fail)) + return (unsigned long *)NULL; +#endif + if ((long)amount <= 0) + { + if (ptr && !amount) + free(ptr); + return (unsigned long *)NULL; + } + amount = (amount + (sizeof(long) - 1)) & ~(sizeof(long) - 1); + if (ptr) + ptr = (pointer)realloc((char *)ptr, amount); + else + ptr = (pointer)malloc(amount); + if (ptr) + return (unsigned long *)ptr; + if (Must_have_memory) + FatalError("Out of memory"); + return (unsigned long *)NULL; +} + +/***************** + * XNFrealloc + * "no failure" realloc, alternate interface to Xrealloc w/o Must_have_memory + *****************/ + +unsigned long * +XNFrealloc (ptr, amount) + register pointer ptr; + unsigned long amount; +{ + if (( ptr = (pointer)Xrealloc( ptr, amount ) ) == NULL) + { + FatalError( "Out of memory" ); + } + return ((unsigned long *)ptr); +} + +/***************** + * Xfree + * calls free + *****************/ + +void +Xfree(ptr) + register pointer ptr; +{ + if (ptr) + free((char *)ptr); +} + +void +FatalError(char *f, ...) +{ + va_list args; + + fprintf(stderr, "\nFatal server error:\n"); + va_start(args, f); + vfprintf(stderr, f, args); + va_end(args); + fprintf(stderr, "\n"); + + exit(1); +} + +#endif diff --git a/zlib.c b/zlib.c new file mode 100644 index 0000000..0749d43 --- /dev/null +++ b/zlib.c @@ -0,0 +1,306 @@ +/* + * zlib.c + * + * Routines to implement zlib based encoding (deflate). + */ + +/* + * Copyright (C) 2000 Tridia Corporation. All Rights Reserved. + * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + * + * For the latest source code, please check: + * + * http://www.developVNC.org/ + * + * or send email to feedback@developvnc.org. + */ + +#include +#include "rfb.h" + +/* + * zlibBeforeBuf contains pixel data in the client's format. + * zlibAfterBuf contains the zlib (deflated) encoding version. + * If the zlib compressed/encoded version is + * larger than the raw data or if it exceeds zlibAfterBufSize then + * raw encoding is used instead. + */ + +static int zlibBeforeBufSize = 0; +static char *zlibBeforeBuf = NULL; + +static int zlibAfterBufSize = 0; +static char *zlibAfterBuf = NULL; +static int zlibAfterBufLen; + +/* + * rfbSendOneRectEncodingZlib - send a given rectangle using one Zlib + * rectangle encoding. + */ + +Bool +rfbSendOneRectEncodingZlib(cl, x, y, w, h) + rfbClientPtr cl; + int x, y, w, h; +{ + rfbFramebufferUpdateRectHeader rect; + rfbZlibHeader hdr; + int deflateResult; + int previousOut; + int i; + char *fbptr = (cl->screen->frameBuffer + (cl->screen->paddedWidthInBytes * y) + + (x * (cl->screen->bitsPerPixel / 8))); + + int maxRawSize; + int maxCompSize; + + maxRawSize = (cl->screen->width * cl->screen->height + * (cl->format.bitsPerPixel / 8)); + + if (zlibBeforeBufSize < maxRawSize) { + zlibBeforeBufSize = maxRawSize; + if (zlibBeforeBuf == NULL) + zlibBeforeBuf = (char *)xalloc(zlibBeforeBufSize); + else + zlibBeforeBuf = (char *)xrealloc(zlibBeforeBuf, zlibBeforeBufSize); + } + + /* zlib compression is not useful for very small data sets. + * So, we just send these raw without any compression. + */ + if (( w * h * (cl->screen->bitsPerPixel / 8)) < + VNC_ENCODE_ZLIB_MIN_COMP_SIZE ) { + + int result; + + /* The translation function (used also by the in raw encoding) + * requires 4/2/1 byte alignment in the output buffer (which is + * updateBuf for the raw encoding) based on the bitsPerPixel of + * the viewer/client. This prevents SIGBUS errors on some + * architectures like SPARC, PARISC... + */ + if (( cl->format.bitsPerPixel > 8 ) && + ( cl->ublen % ( cl->format.bitsPerPixel / 8 )) != 0 ) { + if (!rfbSendUpdateBuf(cl)) + return FALSE; + } + + result = rfbSendRectEncodingRaw(cl, x, y, w, h); + + return result; + + } + + /* + * zlib requires output buffer to be slightly larger than the input + * buffer, in the worst case. + */ + maxCompSize = maxRawSize + (( maxRawSize + 99 ) / 100 ) + 12; + + if (zlibAfterBufSize < maxCompSize) { + zlibAfterBufSize = maxCompSize; + if (zlibAfterBuf == NULL) + zlibAfterBuf = (char *)xalloc(zlibAfterBufSize); + else + zlibAfterBuf = (char *)xrealloc(zlibAfterBuf, zlibAfterBufSize); + } + + /* + * Convert pixel data to client format. + */ + (*cl->translateFn)(cl->translateLookupTable, &cl->screen->rfbServerFormat, + &cl->format, fbptr, zlibBeforeBuf, + cl->screen->paddedWidthInBytes, w, h); + + cl->compStream.next_in = ( Bytef * )zlibBeforeBuf; + cl->compStream.avail_in = w * h * (cl->format.bitsPerPixel / 8); + cl->compStream.next_out = ( Bytef * )zlibAfterBuf; + cl->compStream.avail_out = maxCompSize; + cl->compStream.data_type = Z_BINARY; + + /* Initialize the deflation state. */ + if ( cl->compStreamInited == FALSE ) { + + cl->compStream.total_in = 0; + cl->compStream.total_out = 0; + cl->compStream.zalloc = Z_NULL; + cl->compStream.zfree = Z_NULL; + cl->compStream.opaque = Z_NULL; + + deflateInit2( &(cl->compStream), + cl->zlibCompressLevel, + Z_DEFLATED, + MAX_WBITS, + MAX_MEM_LEVEL, + Z_DEFAULT_STRATEGY ); + /* deflateInit( &(cl->compStream), Z_BEST_COMPRESSION ); */ + /* deflateInit( &(cl->compStream), Z_BEST_SPEED ); */ + cl->compStreamInited = TRUE; + + } + + previousOut = cl->compStream.total_out; + + /* Perform the compression here. */ + deflateResult = deflate( &(cl->compStream), Z_SYNC_FLUSH ); + + /* Find the total size of the resulting compressed data. */ + zlibAfterBufLen = cl->compStream.total_out - previousOut; + + if ( deflateResult != Z_OK ) { + rfbLog("zlib deflation error: %s\n", cl->compStream.msg); + return FALSE; + } + + /* Note that it is not possible to switch zlib parameters based on + * the results of the compression pass. The reason is + * that we rely on the compressor and decompressor states being + * in sync. Compressing and then discarding the results would + * cause lose of synchronization. + */ + + /* Update statics */ + cl->rfbRectanglesSent[rfbEncodingZlib]++; + cl->rfbBytesSent[rfbEncodingZlib] += (sz_rfbFramebufferUpdateRectHeader + + sz_rfbZlibHeader + zlibAfterBufLen); + + if (cl->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbZlibHeader + > UPDATE_BUF_SIZE) + { + if (!rfbSendUpdateBuf(cl)) + return FALSE; + } + + rect.r.x = Swap16IfLE(x); + rect.r.y = Swap16IfLE(y); + rect.r.w = Swap16IfLE(w); + rect.r.h = Swap16IfLE(h); + rect.encoding = Swap32IfLE(rfbEncodingZlib); + + memcpy(&cl->updateBuf[cl->ublen], (char *)&rect, + sz_rfbFramebufferUpdateRectHeader); + cl->ublen += sz_rfbFramebufferUpdateRectHeader; + + hdr.nBytes = Swap32IfLE(zlibAfterBufLen); + + memcpy(&cl->updateBuf[cl->ublen], (char *)&hdr, sz_rfbZlibHeader); + cl->ublen += sz_rfbZlibHeader; + + for (i = 0; i < zlibAfterBufLen;) { + + int bytesToCopy = UPDATE_BUF_SIZE - cl->ublen; + + if (i + bytesToCopy > zlibAfterBufLen) { + bytesToCopy = zlibAfterBufLen - i; + } + + memcpy(&cl->updateBuf[cl->ublen], &zlibAfterBuf[i], bytesToCopy); + + cl->ublen += bytesToCopy; + i += bytesToCopy; + + if (cl->ublen == UPDATE_BUF_SIZE) { + if (!rfbSendUpdateBuf(cl)) + return FALSE; + } + } + + return TRUE; + +} + + +/* + * rfbSendRectEncodingZlib - send a given rectangle using one or more + * Zlib encoding rectangles. + */ + +Bool +rfbSendRectEncodingZlib(cl, x, y, w, h) + rfbClientPtr cl; + int x, y, w, h; +{ + int totalSize = 0; + int partialSize = 0; + int maxLines; + int linesRemaining; + rfbRectangle partialRect; + + partialRect.x = x; + partialRect.y = y; + partialRect.w = w; + partialRect.h = h; + + /* Determine maximum pixel/scan lines allowed per rectangle. */ + maxLines = ( ZLIB_MAX_SIZE(w) / w ); + + /* Initialize number of scan lines left to do. */ + linesRemaining = h; + + /* Loop until all work is done. */ + while ( linesRemaining > 0 ) { + + int linesToComp; + + if ( maxLines < linesRemaining ) + linesToComp = maxLines; + else + linesToComp = linesRemaining; + + partialRect.h = linesToComp; + + /* Encode (compress) and send the next rectangle. */ + if ( ! rfbSendOneRectEncodingZlib( cl, + partialRect.x, + partialRect.y, + partialRect.w, + partialRect.h )) { + + return FALSE; + } + + /* Technically, flushing the buffer here is not extrememly + * efficient. However, this improves the overall throughput + * of the system over very slow networks. By flushing + * the buffer with every maximum size zlib rectangle, we + * improve the pipelining usage of the server CPU, network, + * and viewer CPU components. Insuring that these components + * are working in parallel actually improves the performance + * seen by the user. + * Since, zlib is most useful for slow networks, this flush + * is appropriate for the desired behavior of the zlib encoding. + */ + if (( cl->ublen > 0 ) && + ( linesToComp == maxLines )) { + if (!rfbSendUpdateBuf(cl)) { + + return FALSE; + } + } + + /* Update remaining and incremental rectangle location. */ + linesRemaining -= linesToComp; + partialRect.y += linesToComp; + + } + + return TRUE; + +} + +