diff options
author | Reinhard Tartler <siretart@tauware.de> | 2011-10-10 17:43:39 +0200 |
---|---|---|
committer | Reinhard Tartler <siretart@tauware.de> | 2011-10-10 17:43:39 +0200 |
commit | f4092abdf94af6a99aff944d6264bc1284e8bdd4 (patch) | |
tree | 2ac1c9cc16ceb93edb2c4382c088dac5aeafdf0f /nx-X11/programs/Xserver/hw/xfree86/os-support/os2 | |
parent | a840692edc9c6d19cd7c057f68e39c7d95eb767d (diff) | |
download | nx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.tar.gz nx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.tar.bz2 nx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.zip |
Imported nx-X11-3.1.0-1.tar.gznx-X11/3.1.0-1
Summary: Imported nx-X11-3.1.0-1.tar.gz
Keywords:
Imported nx-X11-3.1.0-1.tar.gz
into Git repository
Diffstat (limited to 'nx-X11/programs/Xserver/hw/xfree86/os-support/os2')
18 files changed, 5114 insertions, 0 deletions
diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/Imakefile b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/Imakefile new file mode 100644 index 000000000..6659da9be --- /dev/null +++ b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/Imakefile @@ -0,0 +1,45 @@ +XCOMM $XConsortium: Imakefile /main/7 1996/09/28 17:24:18 rws $ + + + + + +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/Imakefile,v 3.20 2002/10/17 02:22:48 dawes Exp $ +#include <Server.tmpl> + +BIOS_MOD = os2_bios + +SRCS = os2_init.c os2_video.c os2_io.c $(BIOS_MOD).c \ + os2_ioperm.c os2_VTsw.c os2_mouse.c os2_KbdEv.c os2_stubs.c \ + os2_select.c os2_diag.c libc_wrapper.c stdResource.c stdPci.c \ + vidmem.c sigiostubs.c pm_noop.c kmod_noop.c agp_noop.c os2_serial.c \ + os2_kbd.c + +OBJS = os2_init.o os2_video.o os2_io.o $(BIOS_MOD).o \ + os2_ioperm.o os2_VTsw.o os2_mouse.o os2_kbdEv.o os2_stubs.o \ + os2_select.o os2_diag.o libc_wrapper.o stdResource.o stdPci.o \ + vidmem.o sigiostubs.o pm_noop.o kmod_noop.o agp_noop.o os2_serial.o \ + os2_kbd.o + +INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I. -I$(SERVERSRC)/include \ + -I$(SERVERSRC)/mi -I$(XINCLUDESRC) -I$(EXTINCSRC) + +RESDEFINES = -DUSESTDRES + +DEFINES = $(RESDEFINES) + +SubdirLibraryRule($(OBJS)) +NormalLibraryObjectRule() +NormalAsmObjectRule() + +LinkSourceFile(VTsw_noop.c,../shared) +LinkSourceFile(libc_wrapper.c,../shared) +LinkSourceFile(stdResource.c,../shared) +LinkSourceFile(stdPci.c,../shared) +LinkSourceFile(vidmem.c,../shared) +LinkSourceFile(sigiostubs.c,../shared) +LinkSourceFile(pm_noop.c,../shared) +LinkSourceFile(kmod_noop.c,../shared) +LinkSourceFile(agp_noop.c,../shared) + +DependTarget() diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/README b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/README new file mode 100644 index 000000000..d07059eed --- /dev/null +++ b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/README @@ -0,0 +1,78 @@ +Information on files in this directory +-------------------------------------- +\xc\programs\xserver\hw\xfree86\os-support\os2 + +The files in this directory form the OS-dependent porting layer of +XFree86 for OS/2. They are the work of: + + Holger Veit <Holger.Veit@gmd.de> + Sebastien Marineau <marineau@genie.uottawa.ca> + +Some functions which were absent from OS/2, +such as direct access to IO ports and the mapping of physical memory, +are implemented in a device-driver written for this purpose by Holger Veit +<Holger.Veit@gmd.de>. The driver also implements several functions +necessary for xterm. +The driver should be installed in the config.sys with a line: + +DEVICE=path\XF86SUP.SYS + +The following gives a brief overview of the implementation of the +porting layer, and lists some of the "gotchas" when modifying the source. + +BIOS and physical memory mapping: This is handled by the functions in XF86SUP.SYS driver. + +IO permission: Handled by a function in the XF86SUP.SYS driver. Essentially, IO permissions +are granted for the whole Xserver at server initialisation. The device-driver sets the IOPL +level to ring 3 for the Xserver, which in essence gives it the same IO privileges that a +device-driver has. Note the danger here: the Xserver can write to any IO port it wishes, +and can disable interrupts (something which it does), thus can potentially hang the system. + +VT switching (switching back and forth to the WPS): This is handled by the keyboard driver, +i.e. the stardard keyboard sequences (CTRL-ESC etc.) trigger the switch back to PM. The +Xserver is notified of switches by the VIO function VIOSavRedrawWait(), which is run in +a separate thread. When a switch to/from PM is requested, this function call unblocks, and +the Xserver either saves or restores the video buffer and video mode. Note that semaphores +are used to communicate with the main Xserver thread, and handle cases such as server +reset while the server has lost focus etc. +A similar mechanism is used to handle hard-error popups. A thread is run which blocks +on the VIOModeWait() function. When a hard-error notification occurs, the Xserver attempts +to recover by resetting the screen. Note that, due to some (probable) bugs in the OS/2 +video drivers, this does not always work as expected. According to the specs, the OS/2 +video drivers are supposed to restore the palette when returning from a hard-error. This +does not seem to be always the case..... so the palette in X may be screwed up after the +hard-error. + +Keyboard input: because X needs all keyboard event to function (both keypresses, key +releases, for all keys), the keyboard input was implemented by registering a keyboard +monitor for the Xserver. The keyboard monitor is run in a separate thread, and sends +the keystrokes back to the Xserver main thread through a queue. Another thread is +also started, whose purpose is to "eat" the keystrokes returned by KbdCharIn(). Note that +the monitor was necessary because the OS/2 keyboard driver does not pass all keystrokes +to the application calling KbdCharIn(). + +Mouse input: This was implemented similarly to the keyboard input: mouse events are +read in a thread, which then passes them to the main Xserver thread through a queue. + +Select: this unix and emx function has been reimplemented and optimized for the xserver. +Because of the need to handle input from pipes, sockets, the mouse and keyboard (which +select() in unix does but the EMX select does not), it was decided to rewrite it in +order to minimize CPU usage and maximize responsiveness. Essentially, select() blocks on +a MuxWait semaphore, and unblocks when input is available from pipes, the mouse and the +keyboard. The MuxWait semaphore times out every timeslice, so that sockets can be checked +for activity (unfortunately, sockets are not well-handled in the OS/2 TCPIP and one cannot +attach a semaphore to a socket). There is also the possibility of using the high-resolution +timer (found in Merlin) to check sockets more often than every timeslice. +*** Important: in order to maximize speed, certain shortcuts are utilized in this +implementation of select(), which makes it unsuitable as a general-purpose function. Also, +it is imperative that the EMX select() never be called from the Xserver! *** + + +If you wish to modify the source, be aware that there may be very good reasons as +to why certain things were done this way. Usually, if certain function implementations +appear unnecessarily complicated, it is probably because there were subtle problems +with the simpler solutions. Due to the complexity of the Xserver code, and the +differences between OS/2 and unix, there are many potential pitfalls. + +$XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/README,v 3.1 1996/01/30 15:26:27 dawes Exp $ + diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/int10/Imakefile b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/int10/Imakefile new file mode 100644 index 000000000..a323229bf --- /dev/null +++ b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/int10/Imakefile @@ -0,0 +1,110 @@ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/int10/Imakefile,v 1.1 2000/04/05 18:13:55 dawes Exp $ + +#define IHaveModules + +#include <Server.tmpl> + +SRCS1 = pci.c xf86int10module.c helper_exec.c helper_mem.c xf86int10.c +OBJS1 = pci.o xf86int10module.o helper_exec.o helper_mem.o xf86int10.o + +LinkSourceFile(helper_mem.c,$(XF86SRC)/int10) +LinkSourceFile(helper_exec.c,$(XF86SRC)/int10) +LinkSourceFile(xf86int10.c,$(XF86SRC)/int10) +LinkSourceFile(pci.c,$(XF86SRC)/int10) +LinkSourceFile(xf86int10module.c,$(XF86SRC)/int10) +LinkSourceFile(xf86x86emu.c,$(XF86SRC)/int10) +LinkSourceFile(generic.c,$(XF86SRC)/int10) + +INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86SRC)/int10 \ + -I$(XF86OSSRC) \ + -I$(SERVERSRC)/include -I$(XINCLUDESRC) + +DEFINES=-DHAVE_SYSV_IPC + +#if 0 +/* debugging stuff */ +#DEFINES =-D_PC +#undef XF86INT10_BUILD +#define XF86INT10_BUILD X86EMU_GENERIC +#define X86EMU_LIBPATH /usr/local/lib +#endif + +#if defined(i386Architecture) +DEFINES =-D_PC +#endif + +/* XXX keep this temporarily for reference */ +#if 0 +#if (XF86INT10_BUILD == X86EMU_GENERIC) + +SRCS = $(SRCS1) xf86x86emu.c generic.c +OBJS = $(OBJS1) xf86x86emu.o generic.o x86emu.o +SpecialObjectRule(pci.o, pci.c, -D_X86EMU) +SpecialObjectRule(helper_exec.o, helper_exec.c, -D_X86EMU) +SpecialObjectRule(xf86int10.o, xf86int10.c, -D_X86EMU -DSHOW_ALL_DEVICES) +SpecialObjectRule(generic.o, generic.c, -D_X86EMU) +SpecialObjectRule(xf86x86emu.o, xf86x86emu.c, -D_X86EMU) +BuildObjectFromLibraryWithPath(X86EMU_LIBPATH,x86emu,x86emu) +#endif +#endif + +#if defined(XF86INT10_BUILD) && (XF86INT10_BUILD == X86VM) + +SRCS = $(SRCS1) linux.c +OBJS = $(OBJS1) linux.o +SpecialObjectRule(pci.o, pci.c, -D_VM86_LINUX) +SpecialObjectRule(helper_exec.o, helper_exec.c, -D_VM86_LINUX) +SpecialObjectRule(xf86int10.o, xf86int10.c, -D_VM86_LINUX -DSHOW_ALL_DEVICES) +SpecialObjectRule(linux.o, linux.c, -D_VM86_LINUX -DHAVE_SYSV_IPC) + +#elif (XF86INT10_BUILD == X86EMU_OS) + +SpecialObjectRule(pci.o, pci.c, -D_X86EMU) +SpecialObjectRule(helper_exec.o, helper_exec.c, -D_X86EMU) +SpecialObjectRule(xf86int10.o, xf86int10.c, -D_X86EMU -DSHOW_ALL_DEVICES) +SpecialObjectRule(linux.o, linux.c, -D_X86EMU -DHAVE_SYSV_IPC) + +X86TOPDIR = $(TOP)/extras/x86emu +X86SRCDIR = $(X86TOPDIR)/src/x86emu +X86EMUINCLUDES = -I$(X86TOPDIR)/include -I$(X86SRCDIR) + +# if !defined(X86EMU_LIBPATH) +X86EMUSRCS = debug.c decode.c fpu.c ops.c ops2.c prim_ops.c sys.c +X86EMUOBJS = debug.o decode.o fpu.o ops.o ops2.o prim_ops.o sys.o + +LinkSourceFile(debug.c,$(X86SRCDIR)) +LinkSourceFile(decode.c,$(X86SRCDIR)) +LinkSourceFile(fpu.c,$(X86SRCDIR)) +LinkSourceFile(ops.c,$(X86SRCDIR)) +LinkSourceFile(ops2.c,$(X86SRCDIR)) +LinkSourceFile(prim_ops.c,$(X86SRCDIR)) +LinkSourceFile(sys.c,$(X86SRCDIR)) +# else +BuildObjectFromLibraryWithPath(X86EMU_LIBPATH,x86emu,x86emu) +X86EMUOBJS = x86emu.o +# endif + +SRCS = $(SRCS1) xf86x86emu.c linux.c $(X86EMUSRCS) +OBJS = $(OBJS1) xf86x86emu.o linux.o $(X86EMUOBJS) + +#endif + +#if defined(XF86INT10_BUILD) && XF86INT10_BUILD > X86EMU_GENERIC + +LibraryModuleTarget(int10, $(OBJS)) + +InstallLibraryModule(int10,$(MODULEDIR),linux) + +all:: + @(set -x; cd ../..; \ + RemoveFile(LibraryTargetName(int10)); \ + $(LN) linux/int10/LibraryTargetName(int10) . ) + +InstallDriverSDKLibraryModule(int10,$(DRIVERSDKMODULEDIR),.) + +InstallDriverSDKNonExecFile(../../int10/xf86int10.h,$(DRIVERSDKINCLUDEDIR)) + +#endif + +DependTarget() + diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/int10/os2.c b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/int10/os2.c new file mode 100644 index 000000000..d01cfb373 --- /dev/null +++ b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/int10/os2.c @@ -0,0 +1,452 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/int10/os2.c,v 1.3 2001/04/30 14:34:58 tsi Exp $ */ +/* + * XFree86 int10 module + * execute BIOS int 10h calls in x86 real mode environment + * Copyright 1999 Egbert Eich + */ +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include "xf86.h" +#include "xf86str.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86Pci.h" +#include "compiler.h" +#define _INT10_PRIVATE +#include "xf86int10.h" +#include "int10Defines.h" + +static CARD8 read_b(xf86Int10InfoPtr pInt,int addr); +static CARD16 read_w(xf86Int10InfoPtr pInt,int addr); +static CARD32 read_l(xf86Int10InfoPtr pInt,int addr); +static void write_b(xf86Int10InfoPtr pInt,int addr, CARD8 val); +static void write_w(xf86Int10InfoPtr pInt,int addr, CARD16 val); +static void write_l(xf86Int10InfoPtr pInt,int addr, CARD32 val); + +/* + * the emulator cannot pass a pointer to the current xf86Int10InfoRec + * to the memory access functions therefore store it here. + */ + +typedef struct { + int shift; + int pagesize_1; + int entries; + void* vRam; + memType *alloc_rec; +} genericInt10Priv; + +#define INTPriv(x) ((genericInt10Priv*)x->private) + +int10MemRec genericMem = { + read_b, + read_w, + read_l, + write_b, + write_w, + write_l +}; + +static void MapVRam(xf86Int10InfoPtr pInt); +static void UnmapVRam(xf86Int10InfoPtr pInt); +static void setupTable(xf86Int10InfoPtr pInt, memType address, + int loc,int size); + +static void *sysMem = NULL; + +xf86Int10InfoPtr +xf86InitInt10(int entityIndex) +{ + xf86Int10InfoPtr pInt; + int screen; + void* intMem; + void* vbiosMem; + int pagesize; + int entries; + int shift; + legacyVGARec vga; + + screen = (xf86FindScreenForEntity(entityIndex))->scrnIndex; + + if (int10skip(xf86Screens[screen],entityIndex)) + return NULL; + + pInt = (xf86Int10InfoPtr)xnfcalloc(1,sizeof(xf86Int10InfoRec)); + pInt->entityIndex = entityIndex; + if (!xf86Int10ExecSetup(pInt)) + goto error0; + pInt->mem = &genericMem; + pagesize = xf86getpagesize(); + pInt->private = (pointer)xnfcalloc(1,sizeof(genericInt10Priv)); + entries = SYS_SIZE / pagesize; + + pInt->scrnIndex = screen; + INTPriv(pInt)->pagesize_1 = pagesize - 1; + INTPriv(pInt)->entries = entries; + INTPriv(pInt)->alloc_rec = + xnfcalloc(1,sizeof(memType) * entries); + for (shift = 0 ; (pagesize >> shift) ; shift++) {}; + shift -= 1; + INTPriv(pInt)->shift = shift; + + /* + * we need to map video RAM MMIO as some chipsets map mmio + * registers into this range. + */ + + MapVRam(pInt); + intMem = xnfalloc(pagesize); + setupTable(pInt,(memType)intMem,0,pagesize); + vbiosMem = xnfalloc(V_BIOS_SIZE); + +#ifdef _PC + if (!sysMem) + sysMem = xf86MapVidMem(screen,VIDMEM_FRAMEBUFFER,SYS_BIOS,BIOS_SIZE); + setupTable(pInt,(memType)sysMem,SYS_BIOS,BIOS_SIZE); + if (xf86ReadBIOS(0,0,(unsigned char *)intMem,LOW_PAGE_SIZE) < 0) { + xf86DrvMsg(screen,X_ERROR,"Cannot read int vect\n"); + goto error1; + } + if (xf86IsEntityPrimary(entityIndex)) { + int size; + int cs = MEM_RW(pInt,((0x10<<2)+2)); + +int i,k,m; +char buf[100], hx[10]; +for (i=0; i<0x100; i+=16) { +sprintf(buf,"%04x: ",i); +for (k=0; k<16; k++) { + m = MEM_RB(pInt,i+k); + sprintf(hx,"%02x ",((unsigned)m)&0xff); + strcat(buf,hx); +} +xf86DrvMsg(screen,X_INFO,"%s\n",buf); +} + + + + xf86DrvMsg(screen,X_INFO,"Primary V_BIOS segmant is: 0x%x\n",cs); + if (xf86ReadBIOS(cs << 4,0,(unsigned char *)vbiosMem, + 0x10) < 0) { + xf86DrvMsg(screen,X_ERROR,"Cannot read V_BIOS (1)\n"); + goto error1; + } + if (!((*(CARD8*)vbiosMem == 0x55) + && (*((CARD8*)vbiosMem + 1) == 0xAA))) { + xf86DrvMsg(screen,X_ERROR,"No V_BIOS found\n"); + goto error1; + } + + size = *((CARD8*)vbiosMem + 2) * 512; + if (xf86ReadBIOS(cs << 4,0,vbiosMem, size) < 0) { + xf86DrvMsg(screen,X_ERROR,"Cannot read V_BIOS (2)\n"); + goto error1; + } + + setupTable(pInt,(memType)vbiosMem,cs<<4,size); + set_return_trap(pInt); + pInt->BIOSseg = cs; + } else { + reset_int_vect(pInt); + set_return_trap(pInt); + if (!mapPciRom(pInt,(unsigned char *)(vbiosMem))) { + xf86DrvMsg(screen,X_ERROR,"Cannot read V_BIOS (3)\n"); + goto error1; + } + setupTable(pInt,(memType)vbiosMem,V_BIOS,V_BIOS_SIZE); + pInt->BIOSseg = V_BIOS >> 4; + pInt->num = 0xe6; + LockLegacyVGA(pInt, &vga); + xf86ExecX86int10(pInt); + UnlockLegacyVGA(pInt, &vga); + } +#else + if (!sysMem) { + sysMem = xnfalloc(BIOS_SIZE); + setup_system_bios((memType)sysMem); + } + setupTable(pInt,(memType)sysMem,SYS_BIOS,BIOS_SIZE); + setup_int_vect(pInt); + set_return_trap(pInt); + if (!mapPciRom(pInt,(unsigned char *)(vbiosMem))) { + xf86DrvMsg(screen,X_ERROR,"Cannot read V_BIOS (4)\n"); + goto error1; + } + setupTable(pInt,(memType)vbiosMem,V_BIOS,V_BIOS_SIZE); + pInt->BIOSseg = V_BIOS >> 4; + pInt->num = 0xe6; + LockLegacyVGA(pInt, &vga); + xf86ExecX86int10(pInt); + UnlockLegacyVGA(pInt, &vga); +#endif + return pInt; + + error1: + xfree(vbiosMem); + xfree(intMem); + UnmapVRam(pInt); + xfree(INTPriv(pInt)->alloc_rec); + xfree(pInt->private); + error0: + xfree(pInt); + + return NULL; +} + +static void +MapVRam(xf86Int10InfoPtr pInt) +{ + int screen = pInt->scrnIndex; + int pagesize = INTPriv(pInt)->pagesize_1 + 1; + int size = ((VRAM_SIZE + pagesize - 1)/pagesize) * pagesize; + INTPriv(pInt)->vRam = xf86MapVidMem(screen,VIDMEM_MMIO,V_RAM,size); +} + +static void +UnmapVRam(xf86Int10InfoPtr pInt) +{ + int screen = pInt->scrnIndex; + int pagesize = INTPriv(pInt)->pagesize_1 + 1; + int size = ((VRAM_SIZE + pagesize - 1)/pagesize) * pagesize; + + xf86UnMapVidMem(screen,INTPriv(pInt)->vRam,size); +} + +Bool +MapCurrentInt10(xf86Int10InfoPtr pInt) +{ + /* nothing to do here */ + return TRUE; +} + +void +xf86FreeInt10(xf86Int10InfoPtr pInt) +{ + int pagesize; + + if (!pInt) + return; + pagesize = INTPriv(pInt)->pagesize_1 + 1; + if (Int10Current == pInt) + Int10Current = NULL; + xfree(INTPriv(pInt)->alloc_rec[V_BIOS/pagesize]); + xfree(INTPriv(pInt)->alloc_rec[0]); + UnmapVRam(pInt); + xfree(INTPriv(pInt)->alloc_rec); + xfree(pInt->private); + xfree(pInt); +} + +void * +xf86Int10AllocPages(xf86Int10InfoPtr pInt,int num, int *off) +{ + void* addr; + int pagesize = INTPriv(pInt)->pagesize_1 + 1; + int num_pages = INTPriv(pInt)->entries; + int i,j; + + for (i=0;i<num_pages - num;i++) { + if (INTPriv(pInt)->alloc_rec[i] == 0) { + for (j=i;j < num + i;j++) + if ((INTPriv(pInt)->alloc_rec[j] != 0)) + break; + if (j == num + i) + break; + else + i = i + num; + } + } + if (i == num_pages - num) + return NULL; + + *off = i * pagesize; + addr = xnfalloc(pagesize * num); + setupTable(pInt,(memType)addr,*off,pagesize * num); + + return addr; +} + +void +xf86Int10FreePages(xf86Int10InfoPtr pInt, void *pbase, int num) +{ + int num_pages = INTPriv(pInt)->entries; + int i,j; + for (i = 0;i<num_pages - num; i++) + if (INTPriv(pInt)->alloc_rec[i]==(memType)pbase) { + for (j = 0; j < num; j++) + INTPriv(pInt)->alloc_rec[i] = 0; + break; + } + xfree(pbase); + return; +} + +static void +setupTable(xf86Int10InfoPtr pInt, memType address,int loc,int size) +{ + int pagesize = INTPriv(pInt)->pagesize_1 + 1; + int i,j,num; + + i = loc / pagesize; + num = (size + pagesize - 1)/ pagesize; /* round up to the nearest page */ + /* boudary if size is not */ + /* multiple of pagesize */ + for (j = 0; j<num; j++) { + INTPriv(pInt)->alloc_rec[i+j] = address; + address += pagesize; + } +} + +#define OFF(addr) \ + ((addr) & (INTPriv(pInt)->pagesize_1)) +#define SHIFT \ + (INTPriv(pInt)->shift) +#define BASE(addr,shift) \ + (INTPriv(pInt)->alloc_rec[addr >> shift]) +#define V_ADDR(addr,shift,off) \ + (BASE(addr,shift) + (off)) +#define VRAM_ADDR(addr) (addr - 0xA0000) +#define VRAM_BASE (INTPriv(pInt)->vRam) + +#define VRAM(addr) ((addr >= 0xA0000) && (addr <= 0xBFFFF)) +#define V_ADDR_RB(addr,shift,off) \ + (VRAM(addr)) ? MMIO_IN8((CARD8*)VRAM_BASE,VRAM_ADDR(addr)) \ + : *(CARD8*) V_ADDR(addr,shift,off) +#define V_ADDR_RW(addr,shift,off) \ + (VRAM(addr)) ? MMIO_IN16((CARD16*)VRAM_BASE,VRAM_ADDR(addr)) \ + : ldw_u((pointer)V_ADDR(addr,shift,off)) +#define V_ADDR_RL(addr,shift,off) \ + (VRAM(addr)) ? MMIO_IN32((CARD32*)VRAM_BASE,VRAM_ADDR(addr)) \ + : ldl_u((pointer)V_ADDR(addr,shift,off)) + +#define V_ADDR_WB(addr,shift,off,val) \ + if(VRAM(addr)) \ + MMIO_OUT8((CARD8*)VRAM_BASE,VRAM_ADDR(addr),val); \ + else \ + *(CARD8*) V_ADDR(addr,shift,off) = val; +#define V_ADDR_WW(addr,shift,off,val) \ + if(VRAM(addr)) \ + MMIO_OUT16((CARD16*)VRAM_BASE,VRAM_ADDR(addr),val); \ + else \ + stw_u((val),(pointer)(V_ADDR(addr,shift,off))); + +#define V_ADDR_WL(addr,shift,off,val) \ + if (VRAM(addr)) \ + MMIO_OUT32((CARD32*)VRAM_BASE,VRAM_ADDR(addr),val); \ + else \ + stl_u(val,(pointer)(V_ADDR(addr,shift,off))); + +static CARD8 +read_b(xf86Int10InfoPtr pInt, int addr) +{ + if (!BASE(addr,SHIFT)) return 0xff; + + return V_ADDR_RB(addr,SHIFT,OFF(addr)); +} + +static CARD16 +read_w(xf86Int10InfoPtr pInt, int addr) +{ + int shift = SHIFT; + int off = OFF(addr); + + if (!BASE(addr,shift)) return 0xffff; + +#if X_BYTE_ORDER == X_BIG_ENDIAN + return ((V_ADDR_RB(addr,shift,off)) + || ((V_ADDR_RB(addr,shift,off + 1)) << 8)); +#else + if (OFF(addr + 1) > 0) { + return V_ADDR_RW(addr,SHIFT,OFF(addr)); + } else { + return ((V_ADDR_RB(addr,shift,off + 1)) + || ((V_ADDR_RB(addr,shift,off)) << 8)); + } +#endif +} + +static CARD32 +read_l(xf86Int10InfoPtr pInt, int addr) +{ + int shift = SHIFT; + int off = OFF(addr); + + if (!BASE(addr,shift)) return 0xffffffff; + +#if X_BYTE_ORDER == X_BIG_ENDIAN + return ((V_ADDR_RB(addr,shift,off)) + || ((V_ADDR_RB(addr,shift,off + 1)) << 8) + || ((V_ADDR_RB(addr,shift,off + 2)) << 16) + || ((V_ADDR_RB(addr,shift,off + 3)) << 24)); +#else + if (OFF(addr + 3) > 2) { + return V_ADDR_RL(addr,SHIFT,OFF(addr)); + } else { + return ((V_ADDR_RB(addr,shift,off + 3)) + || ((V_ADDR_RB(addr,shift,off + 2)) << 8) + || ((V_ADDR_RB(addr,shift,off + 1)) << 16) + || ((V_ADDR_RB(addr,shift,off)) << 24)); + } +#endif +} + +static void +write_b(xf86Int10InfoPtr pInt, int addr, CARD8 val) +{ + if (!BASE(addr,SHIFT)) return; + + V_ADDR_WB(addr,SHIFT,OFF(addr),val); +} + +static void +write_w(xf86Int10InfoPtr pInt, int addr, CARD16 val) +{ + int shift = SHIFT; + int off = OFF(addr); + + if (!BASE(addr,shift)) return; + +#if X_BYTE_ORDER == X_BIG_ENDIAN + V_ADDR_WB(addr,shift,off,val); + V_ADDR_WB(addr,shift,off + 1,val >> 8); +#else + if (OFF(addr + 1) > 0) { + V_ADDR_WW(addr,shift,OFF(addr),val); + } else { + V_ADDR_WB(addr,shift,off + 1,val); + V_ADDR_WB(addr,shift,off,val >> 8); + } +#endif +} + +static void +write_l(xf86Int10InfoPtr pInt, int addr, CARD32 val) +{ + int shift = SHIFT; + int off = OFF(addr); + if (!BASE(addr,shift)) return; + +#if X_BYTE_ORDER == X_BIG_ENDIAN + V_ADDR_WB(addr,shift,off,val); + V_ADDR_WB(addr,shift,off + 1, val >> 8); + V_ADDR_WB(addr,shift,off + 2, val >> 16); + V_ADDR_WB(addr,shift,off + 3, val >> 24); +#else + if (OFF(addr + 3) > 2) { + V_ADDR_WL(addr,shift,OFF(addr),val); + } else { + V_ADDR_WB(addr,shift,off + 3, val); + V_ADDR_WB(addr,shift,off + 2, val >> 8); + V_ADDR_WB(addr,shift,off + 1, val >> 16); + V_ADDR_WB(addr,shift,off, val >> 24); + } +#endif +} + +pointer +xf86int10Addr(xf86Int10InfoPtr pInt, CARD32 addr) +{ + return (pointer) V_ADDR(addr,SHIFT,OFF(addr)); +} diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_VTsw.c b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_VTsw.c new file mode 100644 index 000000000..e050a62cb --- /dev/null +++ b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_VTsw.c @@ -0,0 +1,340 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_VTsw.c,v 3.13 2003/06/10 17:03:54 dawes Exp $ */ +/* + * Copyright 1993 by David Wexelblat <dwex@goblin.org> + * Modified 1996 by Sebastien Marineau <marineau@genie.uottawa.ca> + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of David Wexelblat not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. David Wexelblat makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL DAVID WEXELBLAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER 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: os2_VTsw.c /main/7 1996/05/13 16:37:55 kaleb $ */ + +#define I_NEED_OS2_H +#define NEED_EVENTS +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <X11/X.h> +#include "input.h" +#include "scrnintstr.h" + +#define INCL_WINSWITCHLIST +#define INCL_VIO +#define INCL_KBD +#define INCL_DOSPROCESS +#define INCL_DOSSEMAPHORES +#define INCL_DOSERRORS +#undef RT_FONT +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" +#include "atKeynames.h" + +BOOL SwitchedToWPS=FALSE; +BOOL WaitingForAccess=FALSE; +void os2PostKbdEvent(); +HEV hevServerHasFocus; +HEV hevSwitchRequested; +HEV hevErrorPopupDetected; +extern HEV hevPopupPending; +extern HEV hSwitchToSem; +BOOL os2PopupErrorPending=FALSE; + +/* + * Added OS/2 code to handle switching back to WPS + */ + + +Bool xf86VTSwitchPending() +{ + return(xf86Info.vtRequestsPending ? TRUE : FALSE); +} + +Bool xf86VTSwitchAway() +{ + APIRET rc; + ULONG drive; + + xf86Info.vtRequestsPending=FALSE; + SwitchedToWPS=TRUE; + + rc = DosQuerySysInfo(5,5,&drive,sizeof(drive)); + rc = DosSuppressPopUps(0x0000L,drive+96); /* Disable popups */ + DosPostEventSem(hevSwitchRequested); + usleep(30000); + return(TRUE); +} + +Bool xf86VTSwitchTo() +{ + APIRET rc; + ULONG drive,postCount; + + xf86Info.vtRequestsPending=FALSE; + SwitchedToWPS=FALSE; + rc = DosResetEventSem(hSwitchToSem,&postCount); + DosPostEventSem(hevSwitchRequested); + rc = DosQuerySysInfo(5,5,&drive,sizeof(drive)); + rc = DosSuppressPopUps(0x0001L,drive+96); /* Disable popups */ + + /* We reset the state of the control key */ + os2PostKbdEvent(KEY_LCtrl,1); + os2PostKbdEvent(KEY_LCtrl,0); + os2PostKbdEvent(KEY_RCtrl,1); + os2PostKbdEvent(KEY_RCtrl,0); + os2PostKbdEvent(KEY_Alt,1); + os2PostKbdEvent(KEY_Alt,0); + return(TRUE); +} + + +/* This function is run as a thread and will notify of switch-to/switch-away events */ +void os2VideoNotify(arg) +void * arg; +{ + USHORT Indic; + USHORT NotifyType; + APIRET rc; + ULONG postCount; + Bool FirstTime=TRUE; + int timeout_count; + + rc=DosCreateEventSem(NULL,&hevServerHasFocus,0L,FALSE); + rc=DosPostEventSem(hevServerHasFocus); + rc=DosCreateEventSem(NULL,&hevSwitchRequested,0L,FALSE); + rc=DosPostEventSem(hevSwitchRequested); + + + while(1) { + Indic=0; + rc=VioSavRedrawWait(Indic,&NotifyType,(HVIO)0); + +/* Here we handle the semaphore used to indicate wether we have screen access */ + if(NotifyType==0) rc=DosResetEventSem(hevServerHasFocus,&postCount); + if(FirstTime){ + FirstTime=FALSE; + if(NotifyType==1) NotifyType=65535; /* In case a redraw is requested on first call */ + } + + if(NotifyType==1){ +/* Notify os2PseudoSelect() that we are back */ + rc=DosPostEventSem(hSwitchToSem); + if (rc) xf86Msg(X_ERROR,"Post SwitchToSem returned %d\n"); +/* Sanity check */ + if (!SwitchedToWPS) { + xf86Msg(X_ERROR, + "Abnormal switching back to server detected\n"); + } + } + +/* Here we set the semaphore used to indicate switching request */ + + if((NotifyType!=65535)&&(!WaitingForAccess)) { + rc=DosResetEventSem(hevSwitchRequested,&postCount); + xf86Info.vtRequestsPending=TRUE; +/* Then wait for semaphore to be posted once switch is complete. Wait 20 secs, then kill server */ + timeout_count=0; + rc=DosSetPriority(2,3,0,1); + do { + rc=DosWaitEventSem(hevSwitchRequested,1000L); + if(rc==ERROR_TIMEOUT){ + timeout_count++; + if(timeout_count>25){ + xf86Msg(X_ERROR, + "Server timeout on VT switch request. Server was killed\n"); + DosExit(1L,0); + } + if(WaitingForAccess) { /* The server is resetting */ + DosPostEventSem(hevSwitchRequested); + xf86Info.vtRequestsPending=FALSE; + } + } + } while (rc==ERROR_TIMEOUT); + rc=DosSetPriority(2,2,0,1); + } + if(NotifyType==1) rc=DosPostEventSem(hevServerHasFocus); + if((NotifyType==0)&&(!SwitchedToWPS)) + xf86Msg(X_ERROR, + "Abnormal switching away from server!\n"); + } /* endwhile */ + +/* End of thread */ +} + +/* This function is run as a thread and will notify of hard-error events */ +void os2HardErrorNotify(arg) +void * arg; +{ + USHORT Indic; + USHORT NotifyType; + APIRET rc; + ULONG postCount; + + rc=DosCreateEventSem(NULL,&hevErrorPopupDetected,0L,FALSE); + rc=DosPostEventSem(hevErrorPopupDetected); + os2PopupErrorPending=FALSE; + + while(1) { + Indic=0; + rc=VioModeWait(Indic,&NotifyType,(HVIO)0); + if(NotifyType==0){ + os2PopupErrorPending=TRUE; + rc=DosPostEventSem(hSwitchToSem); + rc=DosResetEventSem(hevErrorPopupDetected,&postCount); + rc=DosWaitEventSem(hevErrorPopupDetected,20000L); + if(rc==ERROR_TIMEOUT) GiveUp(0); /* Shutdown on timeout of semaphore */ + } + } /* endwhile */ + +/* End of thread */ +} + +static BOOL is_redirected = FALSE; + +static void +redirect_output(void) +{ + /* hv300996 create redirect file on boot drive, instead + * anywhere you are just standing + */ + char buf[20],dr[3]; + ULONG drive; + APIRET rc; + + if (is_redirected) return; + + if ((rc = DosQuerySysInfo(5,5,&drive,sizeof(drive))) != 0) + dr[0] = 0; + else { + dr[0] = drive+96; + dr[1] = ':'; + dr[2] = 0; + } + sprintf(buf,"%s\\xf86log.os2",dr); + + ErrorF("\nThis is the XFree86/OS2-4.0 server\n"); + ErrorF("\nAll output from now on will be redirected to %s\n",buf); + freopen(buf,"w",stderr); + + is_redirected = TRUE; +} + +void +os2ServerVideoAccess() +{ + APIRET rc; + ULONG fgSession; + ULONG length=4; + CHAR Status; + + /* Redirect output as early as possible */ + /* redirect_output(); */ + /* too many logfiles, server will log to /usr/adm */ + +/* Wait for screen access. This is called at server reset or at server startup */ +/* Here we do some waiting until this session comes in the foreground before * + * going any further. This is because we may have been started in the bg */ + + if(serverGeneration==1){ + rc=VioScrLock(0, &Status, (HVIO)0); + while(Status != 0){ + rc=VioScrLock(0, &Status, (HVIO)0); + DosSleep(1000); + } + VioScrUnLock((HVIO)0); + return; + } + WaitingForAccess=TRUE; + rc=DosWaitEventSem(hevServerHasFocus,SEM_INDEFINITE_WAIT); + WaitingForAccess=FALSE; + SwitchedToWPS=FALSE; /* In case server has reset while we were switched to WPS */ +} + +/* This next function will attempt to recover from a hard error popup + * with an EnterLeave call + */ + +void os2RecoverFromPopup() +{ + int j; + ULONG postCount; + + if (os2PopupErrorPending) { +#if 0 + for (j = 0; j < screenInfo.numScreens; j++) + (XF86SCRNINFO(screenInfo.screens[j])->EnterLeaveVT)(LEAVE, j); + for (j = 0; j < screenInfo.numScreens; j++) + (XF86SCRNINFO(screenInfo.screens[j])->EnterLeaveVT)(ENTER, j); +#endif + DosResetEventSem(hSwitchToSem,&postCount); + + for (j = 0; j < xf86NumScreens; j++) { + if (xf86Screens[j]->EnableDisableFBAccess) + (*xf86Screens[j]->EnableDisableFBAccess)(j, FALSE); + } + xf86EnterServerState(SETUP); + for (j = 0; j < xf86NumScreens; j++) + xf86Screens[j]->LeaveVT(j, 0); + for (j = 0; j < xf86NumScreens; j++) { + xf86Screens[j]->EnterVT(j, 0); + } + xf86EnterServerState(OPERATING); + for (j = 0; j < xf86NumScreens; j++) { + if (xf86Screens[j]->EnableDisableFBAccess) + (*xf86Screens[j]->EnableDisableFBAccess)(j, TRUE); + } + + /* We reset the state of the control key */ + os2PostKbdEvent(KEY_LCtrl,1); + os2PostKbdEvent(KEY_LCtrl,0); + os2PostKbdEvent(KEY_RCtrl,1); + os2PostKbdEvent(KEY_RCtrl,0); + os2PostKbdEvent(KEY_Alt,1); + os2PostKbdEvent(KEY_Alt,0); + + /* Turn screen saver off when switching back */ + SaveScreens(SCREEN_SAVER_FORCER,ScreenSaverReset); + os2PopupErrorPending=FALSE; + DosPostEventSem(hevErrorPopupDetected); + } +} + +/* This checks wether a popup event is waiting. The semaphore would be reset + * by the XF86VIO.DLL function + */ + +void os2CheckPopupPending() +{ + int j; + ULONG postCount; + + return; /* For now this is a no-op */ + +#if 0 + DosQueryEventSem(hevPopupPending,&postCount); + if (postCount==0) { /* We have a popup pending */ +#if 0 + for (j = 0; j < screenInfo.numScreens; j++) + (XF86SCRNINFO(screenInfo.screens[j])->EnterLeaveVT)(LEAVE, j); +#endif + DosPostEventSem(hevPopupPending); + } +#endif +} + diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_bios.c b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_bios.c new file mode 100644 index 000000000..4069ad745 --- /dev/null +++ b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_bios.c @@ -0,0 +1,143 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_bios.c,v 3.10 2000/04/05 18:13:52 dawes Exp $ */ +/* + * (c) Copyright 1994 by Holger Veit + * <Holger.Veit@gmd.de> + * Modified 1996 by Sebastien Marineau <marineau@genie.uottawa.ca> + * + * 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 + * HOLGER VEIT 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 Holger Veit shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Holger Veit. + * + */ +/* $XConsortium: os2_bios.c /main/5 1996/10/27 11:48:45 kaleb $ */ + +#define I_NEED_OS2_H +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <X11/X.h> +#include "input.h" +#include "scrnintstr.h" + +#define INCL_32 +#define INCL_DOS +#define INCL_DOSFILEMGR +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +/* + * Read BIOS via xf86sup.SYS device driver + */ + +static APIRET doioctl(HFILE fd,ULONG addr,ULONG len,unsigned char* dbuf) +{ + UCHAR *dta; + ULONG plen,dlen; + APIRET rc; + + struct { + ULONG command; + ULONG physaddr; + USHORT numbytes; + } par; + + /* prepare parameter and data packets for ioctl */ + par.command = 0; + par.physaddr = addr; + par.numbytes = dlen = len; + plen = sizeof(par); + + /* issue call to get a readonly copy of BIOS ROM */ + rc = DosDevIOCtl(fd, (ULONG)0x76, (ULONG)0x64, + (PVOID)&par, (ULONG)plen, (PULONG)&plen, + (PVOID)dbuf, (ULONG)dlen, (PULONG)&dlen); + + return rc; +} + +int xf86ReadBIOS(Base, Offset, Buf, Len) +unsigned long Base; +unsigned long Offset; +unsigned char *Buf; +int Len; +{ + HFILE fd; + int i; + ULONG action; + APIRET rc; + ULONG Phys_address; + UCHAR* dta; + int off, chunksz,lensave; + + /* allocate dta */ + dta = (UCHAR*)xalloc(Len); + + Phys_address=Base+Offset; + + /* open the special device pmap$ (default with OS/2) */ + if (DosOpen((PSZ)"PMAP$", (PHFILE)&fd, (PULONG)&action, + (ULONG)0, FILE_SYSTEM, FILE_OPEN, + OPEN_SHARE_DENYNONE|OPEN_FLAGS_NOINHERIT|OPEN_ACCESS_READONLY, + (ULONG)0) != 0) { + FatalError("xf86ReadBIOS: install DEVICE=path\\xf86sup.SYS!"); + return -1; + } + + /* copy 32K at a time */ + off = 0; + lensave = Len; + while (Len > 0) { + chunksz = (Len > 32768) ? 32768 : Len; + Len -= chunksz; + rc = doioctl(fd,(ULONG)Phys_address,chunksz,dta+off); + if (rc != 0) { + FatalError("xf86ReadBIOS: BIOS map failed, addr=%lx, rc=%d\n", + Phys_address,rc); + xfree(dta); + DosClose(fd); + return -1; + } + off += chunksz; + } + + /* + * Sanity check... No longer fatal, as some PS/1 and PS/2 fail here but still work. + * S. Marineau, 10/10/96 + */ +#if 0 + if ((Phys_address & 0x7fff) != 0 && + (dta[0] != 0x55 || dta[1] != 0xaa)) { + FatalError("BIOS sanity check failed, addr=%x\nPlease report if you encounter problems\n", + Phys_address); + } +#endif + + /* copy data to buffer */ + memcpy(Buf, dta, lensave); + xfree(dta); + + /* close device */ + DosClose(fd); + + return(lensave); +} diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_diag.c b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_diag.c new file mode 100644 index 000000000..f321df5c2 --- /dev/null +++ b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_diag.c @@ -0,0 +1,263 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_diag.c,v 3.7 2000/04/05 18:13:52 dawes Exp $ */ +/* + * (c) Copyright 1997 by Holger Veit + * <Holger.Veit@gmd.de> + * + * 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 + * HOLGER VEIT 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 Holger Veit shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Holger Veit. + * + */ +/* $XConsortium$ */ + +/* This file checks whether the user has installed the system correctly, + * to avoid the numerous questions why this or that does not work + */ + +#define I_NEED_OS2_H +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <X11/X.h> +#include <X11/Xmd.h> +#include "input.h" +#include "scrnintstr.h" + +#include "compiler.h" + +#define INCL_DOSFILEMGR +#define INCL_KBD +#define INCL_VIO +#define INCL_DOSMISC +#define INCL_DOSPROCESS +#define INCL_DOSSEMAPHORES +#define INCL_DOSMODULEMGR +#define INCL_DOSFILEMGR +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +#include <netdb.h> +#include <sys/socket.h> +#include <netinet/in.h> + +static BOOL diag_checks = FALSE; + +/* from Eberhard to check for the right EMX version */ +static void +check_emx (void) +{ + ULONG rc; + HMODULE hmod; + char name[CCHMAXPATH]; + char fail[9]; + + if (_emx_rev < 50) { + xf86Msg(X_ERROR,"This program requires emx.dll revision 50 (0.9c fix 2) " + "or later.\n"); + rc = DosLoadModule (fail, sizeof (fail), "emx", &hmod); + if (rc == 0) { + rc = DosQueryModuleName (hmod, sizeof (name), name); + if (rc == 0) + xf86Msg(X_ERROR,"Please delete or update `%s'.\n", name); + DosFreeModule (hmod); + } + exit (2); + } +} + +static void +check_bsl(const char *var) +{ + char *t1 = strrchr(var,'\\'); + if (strchr(var,'/')) { + xf86Msg(X_WARNING, + "\"%s\" must exclusively use backward slashes \"\\\"\n", + var); + } + if (t1 && *(t1+1)=='\0') { + xf86Msg(X_WARNING, + "\"%s\" mustn't end with \"\\\"\n",var); + *t1 = '\0'; + } +} + + +static void +check_fsl(const char *var) +{ + char *t1 = strrchr(var,'/'); + if (strchr(var,'\\')) { + xf86Msg(X_WARNING, + "\"%s\" must exclusively use forward slashes \"/\"\n", + var); + } +} + + +static void +check_long(const char* path) +{ + FILE *f; + char n[300]; + + sprintf(n,"%s\\xf86_test_for_very_long_filename",path); + f = fopen(n,"w"); + if (f==NULL) { + xf86Msg(X_WARNING, + "\"%s\" does not accept long filenames\nmust reside on HPFS or similar\n", + path); + } else { + fclose(f); + unlink(n); + } +} + +static char * +check_env_present(const char *env) +{ + char *e = getenv(env); + if (!e) { + xf86Msg(X_WARNING, + "You have no \"%s\" environment variable, but need one\n", + env); + return 0; + } + return e; +} + +void os2_checkinstallation(void) +{ + char *emxopt, *tmp, *home, *logname, *termcap; + char hostname[256], *display, *hostvar, *s, *h; + struct hostent *hent; + struct in_addr *in; + int i; + + if (diag_checks) return; + diag_checks = TRUE; + + /* test whether the EMX version is okay */ + check_emx(); + + /* Check a number of environment variables */ + emxopt = getenv("EMXOPT"); + if (emxopt) { + for (i=0; i<strlen(emxopt); i++) { + if (emxopt[i]=='-') { + switch (emxopt[++i]) { + case 't': + xf86Msg(X_ERROR, + "Remove -t option from EMXOPT variable!\n"); + break; + case 'r': + xf86Msg(X_ERROR, + "Remove -r option from EMXOPT variable!\n"); + } + } + } + } + + tmp = check_env_present("TMP"); + if (tmp) { + check_bsl(tmp); + check_long(tmp); + } + + home = check_env_present("HOME"); + if (home) { + check_bsl(home); + check_long(home); + } + + logname = check_env_present("LOGNAME"); + termcap = check_env_present("TERMCAP"); + if (termcap) + check_fsl(termcap); + + if (gethostname(hostname,sizeof(hostname)) != 0) { + xf86Msg(X_ERROR, + "gethostname() failed: Check TCP/IP setup!\n"); + } else { + xf86Msg(X_INFO, + "gethostname() returns: \"%s\"\n",hostname); + } + + display = check_env_present("DISPLAY"); + if (display) + xf86Msg(X_INFO, + "DISPLAY to listen is set to: \"%s\"\n", + display); + + hostvar = check_env_present("HOSTNAME"); + + strcpy(hostname,display); + h = strchr(hostname,':'); + if (!h) + xf86Msg(X_WARNING, + "Invalid DISPLAY name: expected something like XXX:0.0\n"); + else + *h = 0; + h = strchr(hostname,'/'); + if (h) + h++; + else + h = hostname; + + if (stricmp(h,hostvar)) { + xf86Msg(X_WARNING, + "HOSTNAME does not match DISPLAY: Do you really mean this?\n"); + xf86Msg(X_WARNING, + " This means that xinit/startx and client access may not work\n"); + xf86Msg(X_WARNING, + " which is intentional usually only when connection to a XDM server\n"); + } + + hent = gethostbyname(h); + if (!hent) + xf86Msg(X_ERROR, + "gethostbyname() failed: Check TCP/IP setup\n"); + else { + xf86Msg(X_INFO, + "gethostbyname() returns the following data:\n"); + xf86Msg(X_INFO," official host name: \"%s\"\n",hent->h_name); + while ((s= *(hent->h_aliases)) != NULL) { + xf86Msg(X_INFO, + " alias: \"%s\"\n",s); + hent->h_aliases++; + } + xf86Msg(X_INFO, + " addr type = %d, addr length = %d\n", + hent->h_addrtype, hent->h_length); + if (hent->h_addrtype == AF_INET) { + while ((in= (struct in_addr*)*(hent->h_addr_list++)) != NULL) { + xf86Msg(X_INFO, + " IP address: \"%s\"\n", + inet_ntoa(*in)); + } + } else { + xf86Msg(X_INFO, + "Addrtype should be %d: Check network setup and install TCP/IP support correctly\n", + AF_INET); + } + } +} diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_init.c b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_init.c new file mode 100644 index 000000000..81b2689b8 --- /dev/null +++ b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_init.c @@ -0,0 +1,244 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_init.c,v 3.18 2003/11/29 01:48:31 dawes Exp $ */ +/* + * (c) Copyright 1994 by Holger Veit + * <Holger.Veit@gmd.de> + * Modified 1996 Sebastien Marineau <marineau@genie.uottawa.ca> + * + * 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 + * HOLGER VEIT 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 Holger Veit shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Holger Veit. + * + */ +/* $XConsortium: os2_init.c /main/9 1996/10/19 18:07:13 kaleb $ */ + +#define I_NEED_OS2_H +#define INCL_DOSFILEMGR +#define INCL_KBD +#define INCL_VIO +#define INCL_DOSMISC +#define INCL_DOSPROCESS +#define INCL_DOSSEMAPHORES +#define INCL_DOSMODULEMGR +#define INCL_DOSFILEMGR +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <float.h> +#include <X11/X.h> +#include <X11/Xmd.h> +#include "input.h" +#include "scrnintstr.h" + +#include "compiler.h" + +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +VIOMODEINFO OriginalVideoMode; +void os2VideoNotify(); +void os2HardErrorNotify(); +void os2KbdMonitorThread(); +void os2KbdBitBucketThread(); +HEV hevPopupPending; +extern HEV hKbdSem; +extern BOOL os2HRTimerFlag; +static unsigned short cw; +extern void os2_checkinstallation(); /* os2_diag.c */ + +void xf86OpenConsole() +{ + /* try to catch problems before they become obvious */ + os2_checkinstallation(); + + if (serverGeneration == 1) { + HKBD fd; + ULONG drive; + ULONG dummy; + KBDHWID hwid; + APIRET rc; + int VioTid; + ULONG actual_handles; + LONG new_handles; + + /* hv 250197 workaround for xkb-Problem: switch to X11ROOT drive */ + char *x11r = getenv("X11ROOT"); + /* Make sure X11ROOT is set before we go further sm280297 */ + if (x11r == NULL){ + xf86Msg(X_ERROR, + "Environment variable X11ROOT is not set! Aborting...\n"); + exit(1); + } + if (_chdir2(x11r) < 0) { + xf86Msg(X_ERROR,"Cannot change to X11ROOT directory!\n"); + } + + xf86Msg(X_INFO,"Console opened\n"); + OriginalVideoMode.cb=sizeof(VIOMODEINFO); + rc=VioGetMode(&OriginalVideoMode,(HVIO)0); + if(rc!=0) + xf86Msg(X_ERROR, + "Could not get original video mode. RC=%d\n",rc); + xf86Info.consoleFd = -1; + + /* Set the number of handles to higher than the default 20. Set to 80 which should be plenty */ + new_handles = 0; + rc = DosSetRelMaxFH(&new_handles,&actual_handles); + if (actual_handles < 80) { + new_handles = 80 - actual_handles; + rc = DosSetRelMaxFH(&new_handles,&actual_handles); + xf86Msg(X_INFO,"Increased number of available handles to %d\n", + actual_handles); + } + + /* grab the keyboard */ + rc = KbdGetFocus(0,0); + if (rc != 0) + FatalError("xf86OpenConsole: cannot grab kbd focus, rc=%d\n",rc); + + /* open the keyboard */ + rc = KbdOpen(&fd); + if (rc != 0) + FatalError("xf86OpenConsole: cannot open keyboard, rc=%d\n",rc); + xf86Info.consoleFd = fd; + + xf86Msg(X_INFO,"Keyboard opened\n"); + + /* assign logical keyboard */ + KbdFreeFocus(0); + rc = KbdGetFocus(0,fd); + if (rc != 0) + FatalError("xf86OpenConsole: cannot set local kbd focus, rc=%d\n",rc); + +/* Create kbd queue semaphore */ + + rc = DosCreateEventSem(NULL,&hKbdSem,DC_SEM_SHARED,TRUE); + if (rc != 0) + FatalError("xf86OpenConsole: cannot create keyboard queue semaphore, rc=%d\n",rc); + +/* Create popup semaphore */ + + rc = DosCreateEventSem("\\SEM32\\XF86PUP",&hevPopupPending,DC_SEM_SHARED,1); + if (rc) + xf86Msg(X_ERROR, + "Could not create popup semaphore! RC=%d\n",rc); +#if 0 + rc=VioRegister("xf86vio","XF86POPUP_SUBCLASS",0x20002004L,0L); + if (rc) { + FatalError("Could not register XF86VIO.DLL module. Please install in LIBPATH! RC=%d\n", + rc); + } +#endif + +/* Start up the VIO monitor thread */ + VioTid=_beginthread(os2VideoNotify,NULL,0x4000,(void *)NULL); + xf86Msg(X_INFO,"Started Vio thread, Tid=%d\n",VioTid); + rc=DosSetPriority(2,3,0,VioTid); + +/* Start up the hard-error VIO monitor thread */ + VioTid=_beginthread(os2HardErrorNotify,NULL,0x4000,(void *)NULL); + xf86Msg(X_INFO,"Started hard error Vio mode monitor thread, Tid=%d\n", + VioTid); + rc=DosSetPriority(2,3,0,VioTid); + +/* We have to set the codepage before the keyboard monitor is registered */ + rc = KbdSetCp(0,0,fd); + if(rc != 0) + FatalError("xf86OpenConsole: cannot set keyboard codepage, rc=%d\n",rc); + +/* Start up the kbd monitor thread */ + VioTid=_beginthread(os2KbdMonitorThread,NULL,0x4000,(void *)NULL); + xf86Msg(X_INFO,"Started Kbd monitor thread, Tid=%d\n",VioTid); + rc=DosSetPriority(2,3,0,VioTid); + +/* Disable hard-errors through DosError */ + rc = DosQuerySysInfo(5,5,&drive,sizeof(drive)); + rc = DosSuppressPopUps(0x0001L,drive+96); /* Disable popups */ + + hwid.cb = sizeof(hwid); /* fix crash on P9000 */ + rc = KbdGetHWID(&hwid, fd); + if (rc == 0) { + switch (hwid.idKbd) { + default: + case 0xab54: /* 88/89 key */ + case 0: /*unknown*/ + case 1: /*real AT 84 key*/ + xf86Info.kbdType = KB_84; break; + case 0xab85: /* 122 key */ + FatalError("Unsupported extended 122key keyboard found!\n",0); + case 0xab41: /* 101/102 key */ + xf86Info.kbdType = KB_101; break; + } + } else + xf86Info.kbdType = KB_84; /*defensive*/ + +/* Start up the Kbd bit-bucket thread. We don't want to leave the kbd events in the driver queue */ + VioTid=_beginthread(os2KbdBitBucketThread,NULL,0x2000,(void *)NULL); + xf86Msg(X_INFO,"Started Kbd bit-bucket thread, Tid=%d\n",VioTid); + +/* fg271103: set control word of FPU to default value to prevent SIGFPE in GLX (and elsewhere?) */ + +#define DEFAULT_X86_FPU 0x037f + + cw = _control87(DEFAULT_X86_FPU, 0xFFFF); + xf86Msg(X_INFO,"Checking FPCW: %#x\n",cw); + + if (cw != DEFAULT_X86_FPU) { + cw = _control87(0,0); + xf86Msg(X_INFO,"Set FPCW to %#x\n",cw); + } + + } + return; +} + +void xf86CloseConsole() +{ + APIRET rc; + ULONG drive; + + if (xf86Info.consoleFd != -1) { + KbdClose(xf86Info.consoleFd); + } + VioSetMode(&OriginalVideoMode,(HVIO)0); + rc = DosQuerySysInfo(5,5,&drive,sizeof(drive)); + rc = DosSuppressPopUps(0x0000L,drive+96); /* Reenable popups */ + rc = DosCloseEventSem(hevPopupPending); + rc = VioDeRegister(); + return; +} + +/* ARGSUSED */ + +int xf86ProcessArgument (argc, argv, i) +int argc; +char *argv[]; +int i; +{ + return 0; +} + +void xf86UseMsg() +{ + return; +} + diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_io.c b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_io.c new file mode 100644 index 000000000..e6570aeb9 --- /dev/null +++ b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_io.c @@ -0,0 +1,257 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_io.c,v 3.19 2003/11/17 22:20:41 dawes Exp $ */ +/* + * (c) Copyright 1994,1999 by Holger Veit + * <Holger.Veit@gmd.de> + * Modified 1996 by Sebastien Marineau <marineau@genie.uottawa.ca> + * + * 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 + * HOLGER VEIT 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 Holger Veit shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Holger Veit. + * + */ +/* $XConsortium: os2_io.c /main/9 1996/05/13 16:38:07 kaleb $ */ + +#define I_NEED_OS2_H +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <X11/X.h> +#include <X11/Xpoll.h> +#include "compiler.h" +#include <time.h> + +#define INCL_DOSPROCESS +#define INCL_KBD +#define INCL_MOU +#define INCL_DOSDEVIOCTL +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +int os2MouseQueueQuery(); +int os2KbdQueueQuery(); +void os2RecoverFromPopup(); +void os2CheckPopupPending(); +extern BOOL os2PopupErrorPending; +int _select2 (int, fd_set *, fd_set *,fd_set *, struct timeval *); + + +/***************************************************************************/ + +void xf86SoundKbdBell(loudness, pitch, duration) +int loudness; +int pitch; +int duration; +{ + DosBeep((ULONG)pitch, (ULONG)duration); +} + +void xf86SetKbdLeds(leds) +int leds; +{ + KBDINFO kinfo; + APIRET rc; + + rc = KbdGetStatus(&kinfo,(HKBD)xf86Info.consoleFd); + if (!rc) { + kinfo.fsMask = 0x10; + kinfo.fsState &= ~0x70; + kinfo.fsState |= (leds&0x70); + KbdSetStatus(&kinfo,(HKBD)xf86Info.consoleFd); + } +} + +int xf86GetKbdLeds() +{ + KBDINFO kinfo; + APIRET rc; + + rc = KbdGetStatus(&kinfo,(HKBD)xf86Info.consoleFd); + return rc ? 0 : kinfo.fsState & 0x70; +} + +void xf86SetKbdRepeat(char rad) +{ + int rc; + int delay = 250; /* Default delay */ + int rate = 30; /* Default repeat rate */ + + struct { + USHORT Delay; + USHORT Rate; + } rateDelay; + + ULONG rateDelaySize = sizeof(rateDelay); + + /*notyet*/ + return; + + if (xf86Info.kbdRate >= 0) + rate = xf86Info.kbdRate; + if (xf86Info.kbdDelay >= 0) + delay = xf86Info.kbdDelay; + + rateDelay.Delay = delay; + rateDelay.Rate = rate; + + xf86Msg(X_INFO,"Setting typematic rate: Delay=%d, Rate=%d\n",delay,rate); + + rc = DosDevIOCtl( (HFILE) xf86Info.consoleFd, + IOCTL_KEYBOARD, + KBD_SETTYPAMATICRATE, + &rateDelay, + rateDelaySize, + &rateDelaySize, + NULL, + 0, + NULL); + if (rc!=0) { + xf86Msg(X_ERROR,"xf86SetKbdRepeat: DosDevIOCtl returned %d\n",rc); + } +} + +void xf86KbdInit() +{ + /*none required*/ +} + + +USHORT OrigKbdState; +USHORT OrigKbdInterim; + +typedef struct { + USHORT state; + UCHAR makeCode; + UCHAR breakCode; + USHORT keyID; +} HOTKEYPARAM; + + +int xf86KbdOn() +{ + KBDINFO info; + APIRET rc; + int i,k; + ULONG len; + + + KbdGetStatus(&info,(HKBD)xf86Info.consoleFd); + OrigKbdState=info.fsMask; + OrigKbdInterim=info.fsInterim; + info.fsMask &= ~0x09; + info.fsMask |= 0x136; + info.fsInterim &= ~0x20; + KbdSetStatus(&info,(HKBD)xf86Info.consoleFd); + return -1; +} + +int xf86KbdOff() +{ + ULONG len; + APIRET rc; + KBDINFO info; + + info.fsMask=OrigKbdState; + info.fsInterim=OrigKbdInterim; + KbdSetStatus(&info,(HKBD)xf86Info.consoleFd); + return -1; +} + +#if 0 /*OBSOLETE*/ +void xf86MouseInit(mouse) +MouseDevPtr mouse; +{ + HMOU fd; + APIRET rc; + USHORT nbut; + + if (serverGeneration == 1) { + rc = MouOpen((PSZ)NULL,(PHMOU)&fd); + if (rc != 0) + FatalError("Cannot open mouse, rc=%d\n", rc); + mouse->mseFd = fd; + } + + /* flush mouse queue */ + MouFlushQue(fd); + + /* check buttons */ + rc = MouGetNumButtons(&nbut,fd); + if (rc == 0) + xf86Msg(X_INFO,"OsMouse has %d button(s).\n",nbut); +} +#endif + +#if 0 /*OBSOLETE*/ +int xf86MouseOn(mouse) +MouseDevPtr mouse; +{ +#if 0 + HMOU fd; + APIRET rc; + USHORT nbut; +#endif + xf86Msg (X_ERROR, + "Calling MouseOn, a bad thing.... Must be some bug in the code!\n"); + +#if 0 + if (serverGeneration == 1) { + rc = MouOpen((PSZ)NULL,(PHMOU)&fd); + if (rc != 0) + FatalError("Cannot open mouse, rc=%d\n", rc); + mouse->mseFd = fd; + } + + /* flush mouse queue */ + MouFlushQue(fd); + + /* check buttons */ + rc = MouGetNumButtons(&nbut,fd); + if (rc == 0) + xf86Msg(X_INFO,"OsMouse has %d button(s).\n",nbut); + + return (mouse->mseFd); +#endif +} +#endif + +#if 0 /*OBSOLETE*/ +/* This table is a bit irritating, because these mouse types are infact + * defined in the OS/2 kernel, but I want to force the user to put + * "OsMouse" in the config file, and not worry about the particular mouse + * type that is connected. + */ +Bool xf86SupportedMouseTypes[] = +{ + FALSE, /* Microsoft */ + FALSE, /* MouseSystems */ + FALSE, /* MMSeries */ + FALSE, /* Logitech */ + FALSE, /* BusMouse */ + FALSE, /* MouseMan */ + FALSE, /* PS/2 */ + FALSE, /* Hitachi Tablet */ +}; + +int xf86NumMouseTypes = sizeof(xf86SupportedMouseTypes) / + sizeof(xf86SupportedMouseTypes[0]); +#endif diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_ioperm.c b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_ioperm.c new file mode 100644 index 000000000..c03bb96af --- /dev/null +++ b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_ioperm.c @@ -0,0 +1,140 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_ioperm.c,v 3.5 1997/08/26 10:01:38 hohndel Exp $ */ +/* + * Copyright 1993 by David Wexelblat <dwex@goblin.org> + * Modified 1996 by Sebastien Marineau <marineau@genie.uottawa.ca> + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of David Wexelblat not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. David Wexelblat makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL DAVID WEXELBLAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER 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: os2_ioperm.c /main/4 1996/04/18 16:50:01 kaleb $ */ + + + +#define I_NEED_OS2_H +#define INCL_32 +#define INCL_DOS +#define INCL_DOSFILEMGR +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +/* + * To access I/O ports under OS/2, we use the xf86sup.sys driver. + * For the moment, we use a function which basically grants IO priviledge + * to the whole server. NOTE: Once the server is running, we should + * change this to use inline IO functions through the callgate returned by + * the fastio$ driver. + */ + +int ioEnabled=FALSE; +ULONG action; +char *ioDrvPath = "/dev/fastio$"; +USHORT callgate[3]={0,0,0}; + + +Bool xf86EnableIO() +{ + +HFILE hfd; + ULONG dlen; + APIRET rc; + + /* no need to call multiple times */ + if (ioEnabled) return TRUE; + + if (DosOpen((PSZ)ioDrvPath, (PHFILE)&hfd, (PULONG)&action, + (ULONG)0, FILE_SYSTEM, FILE_OPEN, + OPEN_SHARE_DENYNONE|OPEN_FLAGS_NOINHERIT|OPEN_ACCESS_READONLY, + (ULONG)0) != 0) { + xf86Msg(X_ERROR,"Error opening fastio$ driver...\n"); + xf86Msg(X_ERROR,"Please install xf86sup.sys in config.sys!\n"); + return FALSE; + } + callgate[0] = callgate[1] = 0; + +/* Get callgate from driver for fast io to ports and other stuff */ + + rc = DosDevIOCtl(hfd, (ULONG)0x76, (ULONG)0x64, + NULL, 0, NULL, + (ULONG*)&callgate[2], sizeof(USHORT), &dlen); + if (rc) { + xf86Msg(X_ERROR, + "EnableIOPorts failed, rc=%d, dlen=%d; emergency exit\n", + rc,dlen); + DosClose(hfd); + return FALSE; + } + +/* Calling callgate with function 13 sets IOPL for the program */ + + asm volatile ("movl $13,%%ebx;.byte 0xff,0x1d;.long _callgate" + : /*no outputs */ + : /*no inputs */ + : "eax","ebx","ecx","edx","cc"); + + ioEnabled = TRUE; + DosClose(hfd); + return TRUE; +} + +void xf86DisableIO() +{ +HFILE hfd; + ULONG dlen; + APIRET rc; + + /* no need to call multiple times */ + if (!ioEnabled) return; + + if (DosOpen((PSZ)ioDrvPath, (PHFILE)&hfd, (PULONG)&action, + (ULONG)0, FILE_SYSTEM, FILE_OPEN, + OPEN_SHARE_DENYNONE|OPEN_FLAGS_NOINHERIT|OPEN_ACCESS_READONLY, + (ULONG)0) != 0) { + xf86Msg(X_ERROR,"Error opening fastio$ driver...\n"); + xf86Msg(X_ERROR,"Please install xf86sup.sys in config.sys!\n"); + return; + } + callgate[0] = callgate[1] = 0; + + rc = DosDevIOCtl(hfd, (ULONG)0x76, (ULONG)0x64, + NULL, 0, NULL, + (ULONG*)&callgate[2], sizeof(USHORT), &dlen); + if (rc) { + xf86Msg(X_ERROR,"DisableIOPorts failed, rc=%d, dlen=%d\n", + rc,dlen); + DosClose(hfd); + return; + } + +/* Function 14 of callgate brings program back to ring 3 */ + + asm volatile ("movl $14,%%ebx;.byte 0xff,0x1d;.long _callgate" + : /*no outputs */ + : /*no inputs */ + : "eax","ebx","ecx","edx","cc"); + ioEnabled=FALSE; + DosClose(hfd); + return; + +} + diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_kbd.c b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_kbd.c new file mode 100644 index 000000000..f99f12c0f --- /dev/null +++ b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_kbd.c @@ -0,0 +1,158 @@ +/* + * Copied from os2_io.c which is + * + * (c) Copyright 1994,1999 by Holger Veit + * <Holger.Veit@gmd.de> + * Modified 1996 by Sebastien Marineau <marineau@genie.uottawa.ca> + * + * 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 + * HOLGER VEIT 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 Holger Veit shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Holger Veit. + * + */ +/* $XFree86$ */ + +#define I_NEED_OS2_H +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <X11/X.h> +#include <X11/Xpoll.h> +#include "compiler.h" +#include <time.h> + +#define INCL_DOSPROCESS +#define INCL_KBD +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" +#include "xf86Xinput.h" +#include "xf86OSKbd.h" + + + +/***************************************************************************/ + +static void SoundKbdBell(loudness, pitch, duration) +int loudness; +int pitch; +int duration; +{ + DosBeep((ULONG)pitch, (ULONG)duration); +} + +static void SetKbdLeds(pInfo, leds) +InputInfoPtr pInfo; +int leds; +{ + KBDINFO kinfo; + APIRET rc; + + rc = KbdGetStatus(&kinfo,(HKBD)xf86Info.consoleFd); + if (!rc) { + kinfo.fsMask = 0x10; + kinfo.fsState &= ~0x70; + kinfo.fsState |= (leds&0x70); + KbdSetStatus(&kinfo,(HKBD)xf86Info.consoleFd); + } +} + +static int GetKbdLeds(pInfo) +InputInfoPtr pInfo; +{ + KBDINFO kinfo; + APIRET rc; + + rc = KbdGetStatus(&kinfo,(HKBD)xf86Info.consoleFd); + return rc ? 0 : kinfo.fsState & 0x70; +} + +static void SetKbdRepeat(pInfo, rad) +InputInfoPtr pInfo; +char rad; +{ + /*notyet*/ +} + +static void KbdInit(pInfo) +InputInfoPtr pInfo; +{ + /*none required*/ + xf86Msg(X_INFO,"XKB module: Keyboard initialized\n"); +} + + +static USHORT OrigKbdState; +static USHORT OrigKbdInterim; + +typedef struct { + USHORT state; + UCHAR makeCode; + UCHAR breakCode; + USHORT keyID; +} HOTKEYPARAM; + + +static int KbdOn(pInfo) +InputInfoPtr pInfo; +{ + KBDINFO info; + + KbdGetStatus(&info,(HKBD)xf86Info.consoleFd); + OrigKbdState=info.fsMask; + OrigKbdInterim=info.fsInterim; + info.fsMask &= ~0x09; + info.fsMask |= 0x136; + info.fsInterim &= ~0x20; + KbdSetStatus(&info,(HKBD)xf86Info.consoleFd); + return -1; +} + +static int KbdOff(pInfo) +InputInfoPtr pInfo; +{ + KBDINFO info; + + info.fsMask=OrigKbdState; + info.fsInterim=OrigKbdInterim; + KbdSetStatus(&info,(HKBD)xf86Info.consoleFd); + return -1; +} + +Bool +xf86OSKbdPreInit(InputInfoPtr pInfo) +{ + KbdDevPtr pKbd = pInfo->private; + + pKbd->KbdInit = KbdInit; + pKbd->KbdOn = KbdOn; + pKbd->KbdOff = KbdOff; + pKbd->Bell = SoundKbdBell; + pKbd->SetLeds = SetKbdLeds; + pKbd->GetLeds = GetKbdLeds; + pKbd->SetKbdRepeat = SetKbdRepeat; + + pKbd->vtSwitchSupported = FALSE; + + /* not yet */ + return FALSE; +} diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_kbdEv.c b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_kbdEv.c new file mode 100644 index 000000000..861fbf089 --- /dev/null +++ b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_kbdEv.c @@ -0,0 +1,511 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_kbdEv.c,v 3.16 2002/05/31 18:46:01 dawes Exp $ */ +/* + * (c) Copyright 1994,1996,1999 by Holger Veit + * <Holger.Veit@gmd.de> + * Modified 1996 Sebastien Marineau <marineau@genie.uottawa.ca> + * + * 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 + * HOLGER VEIT 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 Holger Veit shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Holger Veit. + * + */ +/* $XConsortium: os2_kbdEv.c /main/10 1996/10/27 11:48:48 kaleb $ */ + +#define I_NEED_OS2_H +#define NEED_EVENTS +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <X11/X.h> +#include <X11/Xproto.h> +#include "misc.h" +#include "inputstr.h" +#include "scrnintstr.h" + +#define INCL_KBD +#define INCL_DOSMONITORS +#define INCL_WINSWITCHLIST +#define INCL_DOSQUEUES +#undef RT_FONT /* must discard this */ +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" +#include "atKeynames.h" + +/* Attention! these lines copied from ../../common/xf86Events.c */ +#define XE_POINTER 1 +#define XE_KEYBOARD 2 + +#ifdef XKB +extern Bool noXkbExtension; +#endif + +#ifdef XTESTEXT1 + +#define XTestSERVER_SIDE +#include <X11/extensions/xtestext1.h> +extern short xtest_mousex; +extern short xtest_mousey; +extern int on_steal_input; +extern Bool XTestStealKeyData(); +extern void XTestStealMotionData(); + +#ifdef XINPUT +#define ENQUEUE(ev, code, direction, dev_type) \ + (ev)->u.u.detail = (code); \ + (ev)->u.u.type = (direction); \ + if (!on_steal_input || \ + XTestStealKeyData((ev)->u.u.detail, (ev)->u.u.type, dev_type, \ + xtest_mousex, xtest_mousey)) \ + xf86eqEnqueue((ev)) +#else +#define ENQUEUE(ev, code, direction, dev_type) \ + (ev)->u.u.detail = (code); \ + (ev)->u.u.type = (direction); \ + if (!on_steal_input || \ + XTestStealKeyData((ev)->u.u.detail, (ev)->u.u.type, dev_type, \ + xtest_mousex, xtest_mousey)) \ + mieqEnqueue((ev)) +#endif + +#define MOVEPOINTER(dx, dy, time) \ + if (on_steal_input) \ + XTestStealMotionData(dx, dy, XE_POINTER, xtest_mousex, xtest_mousey); \ + miPointerDeltaCursor (dx, dy, time) + +#else /* ! XTESTEXT1 */ + +#ifdef XINPUT +#define ENQUEUE(ev, code, direction, dev_type) \ + (ev)->u.u.detail = (code); \ + (ev)->u.u.type = (direction); \ + xf86eqEnqueue((ev)) +#else +#define ENQUEUE(ev, code, direction, dev_type) \ + (ev)->u.u.detail = (code); \ + (ev)->u.u.type = (direction); \ + mieqEnqueue((ev)) +#endif +#define MOVEPOINTER(dx, dy, time) \ + miPointerDeltaCursor (dx, dy, time) + +#endif +/* end of include */ + +HQUEUE hKbdQueue; +HEV hKbdSem; +int last_status; +int lastStatus; +int lastShiftState; +extern BOOL SwitchedToWPS; + +void os2PostKbdEvent(); + +int os2KbdQueueQuery() +{ + ULONG numElements,postCount; + + (void)DosQueryQueue(hKbdQueue,&numElements); + if (numElements!=0) return 0; /* We have something in queue */ + + DosResetEventSem(hKbdSem,&postCount); + return 1; +} + + +void xf86KbdEvents() +{ + KBDKEYINFO keybuf; + ULONG numElements; + REQUESTDATA requestData; + ULONG dataLength, postCount; + PVOID dummy; + BYTE elemPriority; + int scan, down; + static int last; + USHORT ModState; + int i; + + while(DosReadQueue(hKbdQueue, + &requestData,&dataLength,&dummy, + 0L,1L,&elemPriority,hKbdSem) == 0) { + + /* xf86Msg(X_INFO, + "Got queue element. data=%d, scancode =%d,up=%d, ddflag %d\n", + requestData.ulData, + (requestData.ulData&0x7F00)>>8, + requestData.ulData&0x8000, + requestData.ulData>>16);*/ + + scan=(requestData.ulData&0x7F00)>>8; + + /* the separate cursor keys return 0xe0/scan */ + if ((requestData.ulData & 0x3F0000)==0x20000) scan=0; + if (requestData.ulData & 0x800000) { + switch (scan) { + +/* BUG ALERT: IBM has in its keyboard driver a 122 key keyboard, which + * uses the "server generated scancodes" from atKeynames.h as real scan codes. + * We wait until some poor guy with such a keyboard will break the whole + * card house though... + */ + case KEY_KP_7: scan = KEY_Home; break; + case KEY_KP_8: scan = KEY_Up; break; + case KEY_KP_9: scan = KEY_PgUp; break; + case KEY_KP_4: scan = KEY_Left; break; + case KEY_KP_5: scan = KEY_Begin; break; + case KEY_KP_6: scan = KEY_Right; break; + case KEY_KP_1: scan = KEY_End; break; + case KEY_KP_2: scan = KEY_Down; break; + case KEY_KP_3: scan = KEY_PgDown; break; + case KEY_KP_0: scan = KEY_Insert; break; + case KEY_KP_Decimal: scan = KEY_Delete; break; + case KEY_Enter: scan = KEY_KP_Enter; break; + case KEY_LCtrl: scan = KEY_RCtrl; break; + case KEY_KP_Multiply: scan = KEY_Print; break; + case KEY_Slash: scan = KEY_KP_Divide; break; + case KEY_Alt: scan = KEY_AltLang; break; + case KEY_ScrollLock: scan = KEY_Break; break; + case 0x5b: scan = KEY_LMeta; break; + case 0x5c: scan = KEY_RMeta; break; + case 0x5d: scan = KEY_Menu; break; + default: + /* virtual shifts: ignore */ + scan = 0; break; + } + } + + down = (requestData.ulData&0x8000) ? FALSE : TRUE; + if (scan!=0) os2PostKbdEvent(scan, down); + } + (void)DosResetEventSem(hKbdSem,&postCount); +} + +/* + * xf86PostKbdEvent -- + * Translate the raw hardware KbdEvent into an XEvent, and tell DIX + * about it. Scancode preprocessing and so on is done ... + * + * OS/2 specific xf86PostKbdEvent(key) has been moved from common/xf86Events.c + * as some things differ, and I didn't want to scatter this routine with + * ifdefs further (hv). + */ + +void os2PostKbdEvent(unsigned scanCode, Bool down) +{ + KeyClassRec *keyc = ((DeviceIntPtr)xf86Info.pKeyboard)->key; + Bool updateLeds = FALSE; + Bool UsePrefix = FALSE; + Bool Direction = FALSE; + xEvent kevent; + KeySym *keysym; + int keycode; + static int lockkeys = 0; + + /* + * and now get some special keysequences + */ + if ((ModifierDown(ControlMask | AltMask)) || + (ModifierDown(ControlMask | AltLangMask))) { + switch (scanCode) { + case KEY_BackSpace: + if (!xf86Info.dontZap) GiveUp(0); + return; + case KEY_KP_Minus: /* Keypad - */ + if (!xf86Info.dontZoom) { + if (down) + xf86ZoomViewport(xf86Info.currentScreen, -1); + return; + } + break; + case KEY_KP_Plus: /* Keypad + */ + if (!xf86Info.dontZoom) { + if (down) + xf86ZoomViewport(xf86Info.currentScreen, 1); + return; + } + break; + } + } + + /* CTRL-ESC is std OS/2 hotkey for going back to PM and popping up + * window list... handled by keyboard driverand PM if you tell it. This is + * what we have done, and thus should never detect this key combo */ + if (ModifierDown(ControlMask) && scanCode==KEY_Escape) { + /* eat it */ + return; + } else if (ModifierDown(AltLangMask|AltMask) && scanCode==KEY_Escape) { + /* same here */ + return; + } + + /* + * Now map the scancodes to real X-keycodes ... + */ + keycode = scanCode + MIN_KEYCODE; + keysym = (keyc->curKeySyms.map + + keyc->curKeySyms.mapWidth * + (keycode - keyc->curKeySyms.minKeyCode)); +#ifdef XKB + if (noXkbExtension) { +#endif + /* Filter autorepeated caps/num/scroll lock keycodes. */ + +#define CAPSFLAG 0x01 +#define NUMFLAG 0x02 +#define SCROLLFLAG 0x04 +#define MODEFLAG 0x08 + if (down) { + switch (keysym[0]) { + case XK_Caps_Lock: + if (lockkeys & CAPSFLAG) + return; + else + lockkeys |= CAPSFLAG; + break; + case XK_Num_Lock: + if (lockkeys & NUMFLAG) + return; + else + lockkeys |= NUMFLAG; + break; + case XK_Scroll_Lock: + if (lockkeys & SCROLLFLAG) + return; + else + lockkeys |= SCROLLFLAG; + break; + } + + if (keysym[1] == XF86XK_ModeLock) { + if (lockkeys & MODEFLAG) + return; + else + lockkeys |= MODEFLAG; + } + } else { + switch (keysym[0]) { + case XK_Caps_Lock: + lockkeys &= ~CAPSFLAG; + break; + case XK_Num_Lock: + lockkeys &= ~NUMFLAG; + break; + case XK_Scroll_Lock: + lockkeys &= ~SCROLLFLAG; + break; + } + + if (keysym[1] == XF86XK_ModeLock) + lockkeys &= ~MODEFLAG; + } + + /* + * LockKey special handling: + * ignore releases, toggle on & off on presses. + * Don't deal with the Caps_Lock keysym directly, + * but check the lock modifier + */ +#ifndef PC98 + if (keyc->modifierMap[keycode] & LockMask || + keysym[0] == XK_Scroll_Lock || + keysym[1] == XF86XK_ModeLock || + keysym[0] == XK_Num_Lock) { + Bool flag; + + if (!down) return; + flag = !KeyPressed(keycode); + if (!flag) down = !down; + + if (keyc->modifierMap[keycode] & LockMask) + xf86Info.capsLock = flag; + if (keysym[0] == XK_Num_Lock) + xf86Info.numLock = flag; + if (keysym[0] == XK_Scroll_Lock) + xf86Info.scrollLock = flag; + if (keysym[1] == XF86XK_ModeLock) + xf86Info.modeSwitchLock = flag; + updateLeds = TRUE; + } +#endif /* not PC98 */ + + /* normal, non-keypad keys */ + if (scanCode < KEY_KP_7 || scanCode > KEY_KP_Decimal) { + /* magic ALT_L key on AT84 keyboards for multilingual support */ + if (xf86Info.kbdType == KB_84 && + ModifierDown(AltMask) && + keysym[2] != NoSymbol) { + UsePrefix = TRUE; + Direction = TRUE; + } + } + +#ifdef XKB /* Warning: got position wrong first time */ + } +#endif + + /* check for an autorepeat-event */ + if ((down && KeyPressed(keycode)) && + (xf86Info.autoRepeat != AutoRepeatModeOn || keyc->modifierMap[keycode])) + return; + + xf86Info.lastEventTime = + kevent.u.keyButtonPointer.time = + GetTimeInMillis(); + + /* + * And now send these prefixes ... + * NOTE: There cannot be multiple Mode_Switch keys !!!! + */ + if (UsePrefix) { + ENQUEUE(&kevent, + keyc->modifierKeyMap[keyc->maxKeysPerModifier*7], + Direction ? KeyPress : KeyRelease, + XE_KEYBOARD); + ENQUEUE(&kevent, + keycode, + down ? KeyPress : KeyRelease, + XE_KEYBOARD); + ENQUEUE(&kevent, + keyc->modifierKeyMap[keyc->maxKeysPerModifier*7], + Direction ? KeyRelease : KeyPress, + XE_KEYBOARD); + } else { +#ifdef XFreeDGA + if (((ScrnInfoPtr)(xf86Info.currentScreen->devPrivates[xf86ScreenIndex].ptr))->directMode&XF86DGADirectKeyb) { + XF86DirectVideoKeyEvent(&kevent, + keycode, + down ? KeyPress : KeyRelease); + } else +#endif + { + ENQUEUE(&kevent, + keycode, + down ? KeyPress : KeyRelease, + XE_KEYBOARD); + } + } + + if (updateLeds) xf86KbdLeds(); +} + +#pragma pack(1) +struct KeyPacket { + unsigned short mnflags; + KBDKEYINFO cp; + unsigned short ddflags; +}; +#pragma pack() + +/* The next function runs as a thread. It registers a monitor on the kbd + * driver, and uses that to get keystrokes. This is because the standard + * OS/2 keyboard driver does not send keyboard release events. A queue + * is used to communicate with the main thread to send keystrokes */ + +void os2KbdMonitorThread(void* arg) +{ + struct KeyPacket packet; + APIRET rc; + USHORT length,print_flag; + ULONG queueParam; + HMONITOR hKbdMonitor; + MONIN monInbuf; + MONOUT monOutbuf; + char queueName[128]; + +#if 0 + monInbuf=(MONIN *)_tmalloc(2*sizeof(MONIN)); + if (monInbuf==NULL) { + xf86Msg(X_ERROR, + "Could not allocate memory in kbd monitor thread!\n"); + exit(1); + } + monOutbuf=(MONOUT *) &monInbuf[1]; +#endif + + monInbuf.cb=sizeof(MONIN); + monOutbuf.cb=sizeof(MONOUT); + + rc = DosMonOpen("KBD$",&hKbdMonitor); + xf86Msg(X_INFO,"Opened kbd monitor, rc=%d\n",rc); + rc = DosMonReg(hKbdMonitor, + (PBYTE)&monInbuf,(PBYTE)&monOutbuf,(USHORT)2,(USHORT)-1); + xf86Msg(X_INFO,"Kbd monitor registered, rc=%d\n",rc); + if (rc) { + DosMonClose(hKbdMonitor); + exit(1); + } + + /* create a queue */ + sprintf(queueName,"\\QUEUES\\XF86KBD\\%d",getpid()); + rc = DosCreateQueue(&hKbdQueue,0L,queueName); + xf86Msg(X_INFO,"Kbd Queue created, rc=%d\n",rc); + (void)DosPurgeQueue(hKbdQueue); + + while (1) { + length = sizeof(packet); + rc = DosMonRead((PBYTE)&monInbuf,0,(PBYTE)&packet,&length); + if (rc) { + xf86Msg(X_ERROR, + "DosMonRead returned bad RC! rc=%d\n",rc); + DosMonClose(hKbdMonitor); + exit(1); + } + queueParam = packet.mnflags+(packet.ddflags<<16); + if (packet.mnflags&0x7F00) + DosWriteQueue(hKbdQueue,queueParam,0L,NULL,0L); + /*xf86Msg(X_INFO,"Wrote a char to queue, rc=%d\n",rc); */ + print_flag = packet.ddflags & 0x1F; + + /*xf86Msg(X_INFO,"Kbd Monitor: Key press %d, scan code %d, ddflags %d\n", + packet.mnflags&0x8000,(packet.mnflags&0x7F00)>>8,packet.ddflags); + */ + + /* This line will swallow print-screen keypresses */ + if (print_flag == 0x13 || print_flag == 0x14 || + print_flag == 0x15 || print_flag == 0x16) + rc = 0; + else + rc = DosMonWrite((PBYTE)&monOutbuf,(PBYTE)&packet,length); + if (rc) { + xf86Msg(X_ERROR, + "DosMonWrite returned bad RC! rc=%d\n",rc); + DosMonClose(hKbdMonitor); + exit(1); + } + } + + DosCloseQueue(hKbdQueue); + DosMonClose(hKbdMonitor); +} + +void os2KbdBitBucketThread(void* arg) +{ + KBDKEYINFO key; + while (1) { + if (xf86Info.consoleFd != -1) { + KbdCharIn(&key,1,xf86Info.consoleFd); + usleep(100000); + } else + usleep(500000); + } +} diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_mouse.c b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_mouse.c new file mode 100644 index 000000000..e1fd52c2e --- /dev/null +++ b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_mouse.c @@ -0,0 +1,653 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_mouse.c,v 3.17 2002/05/31 18:46:02 dawes Exp $ */ +/* + * (c) Copyright 1994,1999,2000 by Holger Veit + * <Holger.Veit@gmd.de> + * Modified (c) 1996 Sebastien Marineau <marineau@genie.uottawa.ca> + * + * 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 + * HOLGER VEIT 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 Holger Veit shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Holger Veit. + * + */ +/* $XConsortium: os2_mouse.c /main/10 1996/10/27 11:48:51 kaleb $ */ + +#define I_NEED_OS2_H +#define NEED_EVENTS +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <X11/X.h> +#include <X11/Xproto.h> +#include "misc.h" +#include "inputstr.h" +#include "scrnintstr.h" + +#include "compiler.h" + +#define INCL_DOSFILEMGR +#define INCL_DOSQUEUES +#define INCL_MOU +#undef RT_FONT +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" +#include "xf86Config.h" + +#include "xf86Xinput.h" +#include "xf86OSmouse.h" +#include "mipointer.h" + +/* The following support code was copied from mouse.c */ + +/********************************************************************** + * + * Emulate3Button support code + * + **********************************************************************/ + + +/* + * Lets create a simple finite-state machine for 3 button emulation: + * + * We track buttons 1 and 3 (left and right). There are 11 states: + * 0 ground - initial state + * 1 delayed left - left pressed, waiting for right + * 2 delayed right - right pressed, waiting for left + * 3 pressed middle - right and left pressed, emulated middle sent + * 4 pressed left - left pressed and sent + * 5 pressed right - right pressed and sent + * 6 released left - left released after emulated middle + * 7 released right - right released after emulated middle + * 8 repressed left - left pressed after released left + * 9 repressed right - right pressed after released right + * 10 pressed both - both pressed, not emulating middle + * + * At each state, we need handlers for the following events + * 0: no buttons down + * 1: left button down + * 2: right button down + * 3: both buttons down + * 4: emulate3Timeout passed without a button change + * Note that button events are not deltas, they are the set of buttons being + * pressed now. It's possible (ie, mouse hardware does it) to go from (eg) + * left down to right down without anything in between, so all cases must be + * handled. + * + * a handler consists of three values: + * 0: action1 + * 1: action2 + * 2: new emulation state + * + * action > 0: ButtonPress + * action = 0: nothing + * action < 0: ButtonRelease + * + * The comment preceeding each section is the current emulation state. + * The comments to the right are of the form + * <button state> (<events>) -> <new emulation state> + * which should be read as + * If the buttons are in <button state>, generate <events> then go to + * <new emulation state>. + */ +static signed char stateTab[11][5][3] = { +/* 0 ground */ + { + { 0, 0, 0 }, /* nothing -> ground (no change) */ + { 0, 0, 1 }, /* left -> delayed left */ + { 0, 0, 2 }, /* right -> delayed right */ + { 2, 0, 3 }, /* left & right (middle press) -> pressed middle */ + { 0, 0, -1 } /* timeout N/A */ + }, +/* 1 delayed left */ + { + { 1, -1, 0 }, /* nothing (left event) -> ground */ + { 0, 0, 1 }, /* left -> delayed left (no change) */ + { 1, -1, 2 }, /* right (left event) -> delayed right */ + { 2, 0, 3 }, /* left & right (middle press) -> pressed middle */ + { 1, 0, 4 }, /* timeout (left press) -> pressed left */ + }, +/* 2 delayed right */ + { + { 3, -3, 0 }, /* nothing (right event) -> ground */ + { 3, -3, 1 }, /* left (right event) -> delayed left (no change) */ + { 0, 0, 2 }, /* right -> delayed right (no change) */ + { 2, 0, 3 }, /* left & right (middle press) -> pressed middle */ + { 3, 0, 5 }, /* timeout (right press) -> pressed right */ + }, +/* 3 pressed middle */ + { + { -2, 0, 0 }, /* nothing (middle release) -> ground */ + { 0, 0, 7 }, /* left -> released right */ + { 0, 0, 6 }, /* right -> released left */ + { 0, 0, 3 }, /* left & right -> pressed middle (no change) */ + { 0, 0, -1 }, /* timeout N/A */ + }, +/* 4 pressed left */ + { + { -1, 0, 0 }, /* nothing (left release) -> ground */ + { 0, 0, 4 }, /* left -> pressed left (no change) */ + { -1, 0, 2 }, /* right (left release) -> delayed right */ + { 3, 0, 10 }, /* left & right (right press) -> pressed both */ + { 0, 0, -1 }, /* timeout N/A */ + }, +/* 5 pressed right */ + { + { -3, 0, 0 }, /* nothing (right release) -> ground */ + { -3, 0, 1 }, /* left (right release) -> delayed left */ + { 0, 0, 5 }, /* right -> pressed right (no change) */ + { 1, 0, 10 }, /* left & right (left press) -> pressed both */ + { 0, 0, -1 }, /* timeout N/A */ + }, +/* 6 released left */ + { + { -2, 0, 0 }, /* nothing (middle release) -> ground */ + { -2, 0, 1 }, /* left (middle release) -> delayed left */ + { 0, 0, 6 }, /* right -> released left (no change) */ + { 1, 0, 8 }, /* left & right (left press) -> repressed left */ + { 0, 0, -1 }, /* timeout N/A */ + }, +/* 7 released right */ + { + { -2, 0, 0 }, /* nothing (middle release) -> ground */ + { 0, 0, 7 }, /* left -> released right (no change) */ + { -2, 0, 2 }, /* right (middle release) -> delayed right */ + { 3, 0, 9 }, /* left & right (right press) -> repressed right */ + { 0, 0, -1 }, /* timeout N/A */ + }, +/* 8 repressed left */ + { + { -2, -1, 0 }, /* nothing (middle release, left release) -> ground */ + { -2, 0, 4 }, /* left (middle release) -> pressed left */ + { -1, 0, 6 }, /* right (left release) -> released left */ + { 0, 0, 8 }, /* left & right -> repressed left (no change) */ + { 0, 0, -1 }, /* timeout N/A */ + }, +/* 9 repressed right */ + { + { -2, -3, 0 }, /* nothing (middle release, right release) -> ground */ + { -3, 0, 7 }, /* left (right release) -> released right */ + { -2, 0, 5 }, /* right (middle release) -> pressed right */ + { 0, 0, 9 }, /* left & right -> repressed right (no change) */ + { 0, 0, -1 }, /* timeout N/A */ + }, +/* 10 pressed both */ + { + { -1, -3, 0 }, /* nothing (left release, right release) -> ground */ + { -3, 0, 4 }, /* left (right release) -> pressed left */ + { -1, 0, 5 }, /* right (left release) -> pressed right */ + { 0, 0, 10 }, /* left & right -> pressed both (no change) */ + { 0, 0, -1 }, /* timeout N/A */ + }, +}; + +/* + * Table to allow quick reversal of natural button mapping to correct mapping + */ + +/* + * [JCH-96/01/21] The ALPS GlidePoint pad extends the MS protocol + * with a fourth button activated by tapping the PAD. + * The 2nd line corresponds to 4th button on; the drv sends + * the buttons in the following map (MSBit described first) : + * 0 | 4th | 1st | 2nd | 3rd + * And we remap them (MSBit described first) : + * 0 | 4th | 3rd | 2nd | 1st + */ +static char reverseMap[32] = { 0, 4, 2, 6, 1, 5, 3, 7, + 8, 12, 10, 14, 9, 13, 11, 15, + 16, 20, 18, 22, 17, 21, 19, 23, + 24, 28, 26, 30, 25, 29, 27, 31}; + + +static char hitachMap[16] = { 0, 2, 1, 3, + 8, 10, 9, 11, + 4, 6, 5, 7, + 12, 14, 13, 15 }; + +#define reverseBits(map, b) (((b) & ~0x0f) | map[(b) & 0x0f]) + +static CARD32 +buttonTimer(InputInfoPtr pInfo) +{ + MouseDevPtr pMse; + int sigstate; + int id; + + pMse = pInfo->private; + + sigstate = xf86BlockSIGIO (); + + pMse->emulate3Pending = FALSE; + if ((id = stateTab[pMse->emulateState][4][0]) != 0) { + xf86PostButtonEvent(pInfo->dev, 0, abs(id), (id >= 0), 0, 0); + pMse->emulateState = stateTab[pMse->emulateState][4][2]; + } else { + ErrorF("Got unexpected buttonTimer in state %d\n", pMse->emulateState); + } + + xf86UnblockSIGIO (sigstate); + return 0; +} + +static Bool +Emulate3ButtonsSoft(InputInfoPtr pInfo) +{ + MouseDevPtr pMse = pInfo->private; + + if (!pMse->emulate3ButtonsSoft) + return TRUE; + + pMse->emulate3Buttons = FALSE; + + if (pMse->emulate3Pending) + buttonTimer(pInfo); + + xf86Msg(X_INFO,"3rd Button detected: disabling emulate3Button\n"); + + return FALSE; +} + +static void MouseBlockHandler(pointer data, + struct timeval **waitTime, + pointer LastSelectMask) +{ + InputInfoPtr pInfo = (InputInfoPtr) data; + MouseDevPtr pMse = (MouseDevPtr) pInfo->private; + int ms; + + if (pMse->emulate3Pending) + { + ms = pMse->emulate3Expires - GetTimeInMillis (); + if (ms <= 0) + ms = 0; + AdjustWaitForDelay (waitTime, ms); + } +} + +static void MouseWakeupHandler(pointer data, + int i, + pointer LastSelectMask) +{ + InputInfoPtr pInfo = (InputInfoPtr) data; + MouseDevPtr pMse = (MouseDevPtr) pInfo->private; + int ms; + + if (pMse->emulate3Pending) + { + ms = pMse->emulate3Expires - GetTimeInMillis (); + if (ms <= 0) + buttonTimer (pInfo); + } +} + +static int +SupportedInterfaces(void) +{ + return MSE_MISC; +} + +static const char* internalNames[] = { + "OS2Mouse", + NULL +}; + +static const char** +BuiltinNames(void) +{ + return internalNames; +} + +static Bool +CheckProtocol(const char *protocol) +{ + int i; + + for (i = 0; internalNames[i]; i++) + if (xf86NameCmp(protocol, internalNames[i]) == 0) + return TRUE; + return FALSE; +} + +static const char * +DefaultProtocol(void) +{ + return "OS2Mouse"; +} + +static const char * +SetupAuto(InputInfoPtr pInfo, int *protoPara) +{ + return "OS2Mouse"; +} + +HMOU hMouse=65535; +HEV hMouseSem; +HQUEUE hMouseQueue; +InputInfoPtr iinfoPtr; +int MouseTid; +BOOL HandleValid=FALSE; +extern BOOL SwitchedToWPS; +extern CARD32 LastSwitchTime; +void os2MouseEventThread(void* arg); + +static void +os2MouseReadInput(InputInfoPtr pInfo) +{ + APIRET rc; + ULONG postCount,dataLength; + PVOID dummy; + int buttons; + int state; + int i, dx,dy; + BYTE elemPriority; + REQUESTDATA requestData; + + MouseDevPtr pMse = pInfo->private; + + if (!HandleValid) return; + while((rc = DosReadQueue(hMouseQueue, + &requestData,&dataLength,&dummy, + 0L,1L,&elemPriority,hMouseSem)) == 0) { + dx = requestData.ulData; + (void)DosReadQueue(hMouseQueue, + &requestData,&dataLength,&dummy, + 0L,1L,&elemPriority,hMouseSem); + dy = requestData.ulData; + (void)DosReadQueue(hMouseQueue, + &requestData,&dataLength,&dummy, + 0L,1L,&elemPriority,hMouseSem); + state = requestData.ulData; + (void)DosReadQueue(hMouseQueue, + &requestData,&dataLength,&dummy, + 0L,1L,&elemPriority,hMouseSem); + if (requestData.ulData != 0xFFFFFFFF) + xf86Msg(X_ERROR, + "Unexpected mouse event tag, %d\n", + requestData.ulData); + + /* Contrary to other systems, OS/2 has mouse buttons * + * in the proper order, so we reverse them before * + * sending the event. */ + + buttons = ((state & 0x06) ? 4 : 0) | + ((state & 0x18) ? 1 : 0) | + ((state & 0x60) ? 2 : 0); + pMse->PostEvent(pInfo, buttons, dx, dy, 0, 0); + } + DosResetEventSem(hMouseSem,&postCount); +} + +int os2MouseProc(DeviceIntPtr pPointer, int what) +{ + APIRET rc = 0; + USHORT nbuttons, state; + unsigned char map[MSE_MAXBUTTONS + 1]; + int i; + + InputInfoPtr pInfo = pPointer->public.devicePrivate; + MouseDevPtr pMse = pInfo->private; + pMse->device = pPointer; + + switch (what) { + case DEVICE_INIT: + pPointer->public.on = FALSE; + if (hMouse == 65535) + rc = MouOpen((PSZ)0, &hMouse); + if (rc != 0) + xf86Msg(X_WARNING,"%s: cannot open mouse, rc=%d\n", + pInfo->name,rc); + else { + pInfo->fd = hMouse; + + /* flush mouse queue */ + MouFlushQue(hMouse); + + /* check buttons */ + rc = MouGetNumButtons(&nbuttons, hMouse); + if (rc == 0) + xf86Msg(X_INFO,"%s: Mouse has %d button(s).\n", + pInfo->name,nbuttons); + if (nbuttons==2) nbuttons++; + + for (i = 1; i<=nbuttons; i++) + map[i] = i; + + InitPointerDeviceStruct((DevicePtr)pPointer, map, nbuttons, + miPointerGetMotionEvents, pMse->Ctrl, + miPointerGetMotionBufferSize()); + + /* X valuator */ + xf86InitValuatorAxisStruct(pPointer, 0, 0, -1, 1, 0, 1); + xf86InitValuatorDefaults(pPointer, 0); + /* y Valuator */ + InitValuatorAxisStruct(pPointer, 1, 0, -1, 1, 0, 1); + xf86InitValuatorDefaults(pPointer, 1); + xf86MotionHistoryAllocate(pInfo); + + /* OK, we are ready to start up the mouse thread ! */ + if (!HandleValid) { + rc = DosCreateEventSem(NULL,&hMouseSem,DC_SEM_SHARED,TRUE); + if (rc != 0) + xf86Msg(X_ERROR,"%s: could not create mouse queue semaphore, rc=%d\n", + pInfo->name,rc); + MouseTid = _beginthread(os2MouseEventThread,NULL,0x4000,(void *)pInfo); + xf86Msg(X_INFO, + "%s: Started Mouse event thread, Tid=%d\n", + pInfo->name, MouseTid); + DosSetPriority(2,3,0,MouseTid); + } + HandleValid=TRUE; + } + break; + + case DEVICE_ON: + if (!HandleValid) return -1; + pMse->lastButtons = 0; + pMse->lastMappedButtons = 0; + pMse->emulateState = 0; + pPointer->public.on = TRUE; + state = 0x300; + rc = MouSetDevStatus(&state,hMouse); + state = 0x7f; + rc = MouSetEventMask(&state,hMouse); + MouFlushQue(hMouse); + if (pMse->emulate3Buttons || pMse->emulate3ButtonsSoft) + { + RegisterBlockAndWakeupHandlers (MouseBlockHandler, MouseWakeupHandler, + (pointer) pInfo); + } + break; + + case DEVICE_CLOSE: + case DEVICE_OFF: + if (!HandleValid) return -1; + if (pMse->emulate3Buttons || pMse->emulate3ButtonsSoft) + { + RemoveBlockAndWakeupHandlers (MouseBlockHandler, MouseWakeupHandler, + (pointer) pInfo); + } + pPointer->public.on = FALSE; + state = 0x300; + MouSetDevStatus(&state,hMouse); + state = 0; + MouSetEventMask(&state,hMouse); + if (what == DEVICE_CLOSE) { +/* Comment out for now as this seems to break server */ +#if 0 + MouClose(hMouse); + hMouse = 65535; + pInfo->fd = -1; + HandleValid = FALSE; +#endif + } + break; + } + return Success; +} + +int os2MouseQueueQuery() +{ + /* Now we check for activity on mouse handles */ + ULONG numElements,postCount; + + if (!HandleValid) return(1); + DosResetEventSem(hMouseSem,&postCount); + (void)DosQueryQueue(hMouseQueue,&numElements); + if (numElements>0) { /* Something in mouse queue! */ + return 0; /* Will this work? */ + } + return 1; +} + +void os2MouseEventThread(void *arg) +{ + APIRET rc; + MOUEVENTINFO mev; + ULONG queueParam; + USHORT waitflg; + char queueName[128]; + MouseDevPtr pMse; + + iinfoPtr = (InputInfoPtr)arg; + pMse = iinfoPtr->private; + + sprintf(queueName,"\\QUEUES\\XF86MOU\\%d",getpid()); + rc = DosCreateQueue(&hMouseQueue,0L,queueName); + xf86Msg(X_INFO,"Mouse Queue created, rc=%d\n",rc); + (void)DosPurgeQueue(hMouseQueue); + + while(1) { + waitflg = 1; + rc = MouReadEventQue(&mev,&waitflg,hMouse); + if (rc) { + xf86Msg(X_ERROR, + "Bad return code from mouse driver, rc=%d\n", + rc); + xf86Msg(X_ERROR,"Mouse aborting!\n"); + break; + } + + queueParam = mev.col; + if ((rc = DosWriteQueue(hMouseQueue,queueParam,0L,NULL,0L))) + break; + queueParam = mev.row; + if ((rc = DosWriteQueue(hMouseQueue,queueParam,0L,NULL,0L))) + break; + queueParam = mev.fs; + if ((rc = DosWriteQueue(hMouseQueue,queueParam,0L,NULL,0L))) + break; + queueParam = 0xFFFFFFFF; + if ((rc = DosWriteQueue(hMouseQueue,queueParam,0L,NULL,0L))) + break; + } + xf86Msg(X_ERROR, + "An unrecoverable error in mouse queue has occured, rc=%d. Mouse is shutting down.\n", + rc); + DosCloseQueue(hMouseQueue); +} + + +static Bool +os2MousePreInit(InputInfoPtr pInfo, const char* protocol, int flags) +{ + MouseDevPtr pMse = pInfo->private; + + pMse->protocol = protocol; + xf86Msg(X_CONFIG, "%s: Protocol: %s\n", pInfo->name, protocol); + + /* Collect the options, and process the common options. */ + xf86CollectInputOptions(pInfo, NULL, NULL); + xf86ProcessCommonOptions(pInfo, pInfo->options); + + /* Process common mouse options (like Emulate3Buttons, etc). */ + pMse->CommonOptions(pInfo); + + /* Setup the local procs. */ + pInfo->device_control = os2MouseProc; + pInfo->read_input = os2MouseReadInput; + + pInfo->flags |= XI86_CONFIGURED; + return TRUE; +} + +OSMouseInfoPtr +xf86OSMouseInit(int flags) +{ + OSMouseInfoPtr p; + + p = xcalloc(sizeof(OSMouseInfoRec), 1); + if (!p) + return NULL; + p->SupportedInterfaces = SupportedInterfaces; + p->BuiltinNames = BuiltinNames; + p->DefaultProtocol = DefaultProtocol; + p->CheckProtocol = CheckProtocol; + p->PreInit = os2MousePreInit; + p->SetupAuto = SetupAuto; + return p; +} + +void xf86OsMouseEvents() +{ + APIRET rc; + ULONG postCount,dataLength; + PVOID dummy; + int buttons; + int state; + int i, dx,dy; + BYTE elemPriority; + REQUESTDATA requestData; + + MouseDevPtr pMse = iinfoPtr->private; + + if (!HandleValid) return; + while((rc = DosReadQueue(hMouseQueue, + &requestData,&dataLength,&dummy, + 0L,1L,&elemPriority,hMouseSem)) == 0) { + dx = requestData.ulData; + (void)DosReadQueue(hMouseQueue, + &requestData,&dataLength,&dummy, + 0L,1L,&elemPriority,hMouseSem); + dy = requestData.ulData; + (void)DosReadQueue(hMouseQueue, + &requestData,&dataLength,&dummy, + 0L,1L,&elemPriority,hMouseSem); + state = requestData.ulData; + (void)DosReadQueue(hMouseQueue, + &requestData,&dataLength,&dummy, + 0L,1L,&elemPriority,hMouseSem); + if (requestData.ulData != 0xFFFFFFFF) + xf86Msg(X_ERROR, + "Unexpected mouse event tag, %d\n", + requestData.ulData); + + /* Contrary to other systems, OS/2 has mouse buttons * + * in the proper order, so we reverse them before * + * sending the event. */ + + buttons = ((state & 0x06) ? 4 : 0) | + ((state & 0x18) ? 1 : 0) | + ((state & 0x60) ? 2 : 0); + pMse->PostEvent(iinfoPtr, buttons, dx, dy, 0, 0); + } + DosResetEventSem(hMouseSem,&postCount); +} diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_select.c b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_select.c new file mode 100644 index 000000000..395104242 --- /dev/null +++ b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_select.c @@ -0,0 +1,497 @@ +/* $XConsortium: os2_select.c /main/6 1996/10/27 11:48:55 kaleb $ */ + + + + +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_select.c,v 3.9 2003/03/25 04:18:24 dawes Exp $ */ + +/* + * (c) Copyright 1996 by Sebastien Marineau + * <marineau@genie.uottawa.ca> + * Modified 1999 by Holger.Veit@gmd.de + * Modified 2004 by Frank Giessler + * <giessler@biomag.uni-jena.de> + * + * 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 + * HOLGER VEIT 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 Sebastien Marineau shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Sebastien Marineau. + * + */ + +/* os2_select.c: reimplementation of the xserver select(), optimized for speed */ + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <stdlib.h> +#include <stdio.h> +#include <memory.h> +#include <io.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/errno.h> +#include <emx/io.h> + +#define I_NEED_OS2_H +#define INCL_DOSSEMAPHORES +#define INCL_DOSPROFILE +#define INCL_DOSPROCESS +#define INCL_DOSFILEMGR +#define INCL_DOSMISC +#define INCL_DOSMODULEMGR + + +#include <X11/Xpoll.h> +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +#include "os2_select.h" + +int os2MouseQueueQuery(); +int os2KbdQueueQuery(); +void os2RecoverFromPopup(); +void os2CheckPopupPending(); +void os2SocketMonitorThread(); +extern BOOL os2PopupErrorPending; + +extern HEV hKbdSem; +extern HEV hMouseSem; +extern HEV hevServerHasFocus; +HEV hPipeSem; +HEV hSocketSem; +HEV hActivateSocketSem; +HEV hSwitchToSem; +static HMUX hSelectWait; +SEMRECORD SelectMuxRecord[5]; +HMODULE hmod_so32dll; +static struct select_data sd; + +static int (*os2_tcp_select)(int *,int,int,int,long); +static int (*os2_so_cancel)(int); +static int (*os2_sock_errno)(); +int os2_set_error(ULONG); +extern int _files[]; + + + +/* This is a new implementation of select, for improved efficiency */ +/* This function performs select() on sockets */ +/* but uses OS/2 internal fncts to check mouse */ +/* and keyboard. S. Marineau, 27/4/96 */ + +/* This is still VERY messy */ + +/* A few note on optimizations: this select has been tuned for maximum +* performance, and thus has a different approach than a general-purpose +* select. It should not be used in another app without modifications. Further, +* it may need modifications if the Xserver os code is modified +* Assumptions: this is never called with anything in exceptfds. This is +* silently ignored. Further, if any pipes are specified in the write mask, it is +* because they have just been stuffed full by the xserver. There is not much +* in immediately returning with those bits set. Instead, we block on the +* semaphore for at least one tick, which will let the client at least start +* to flush the pipe. */ + +int os2PseudoSelect(nfds,readfds,writefds,exceptfds,timeout) + int nfds; + fd_set *readfds,*writefds,*exceptfds; + struct timeval *timeout; +{ + + static BOOL FirstTime=TRUE; + + int n,ns,np; + int ready_handles; + ULONG timeout_ms; + BOOL any_ready; + ULONG semKey,postCount; + APIRET rc; + char faildata[16]; + static int Socket_Tid; + + sd.have_read=FALSE; sd.have_write=FALSE; + sd.socket_nread=0; sd.socket_nwrite=0; sd.socket_ntotal=0; + sd.max_fds=31; ready_handles=0; any_ready=FALSE; + sd.pipe_ntotal=0; sd.pipe_have_write=FALSE; + + /* Stuff we have to do the first time this is called to set up various parameters */ + + if (FirstTime) { + /* First load the so32dll.dll module and get a pointer to the SELECT fn */ + + if ((rc=DosLoadModule(faildata,sizeof(faildata),"SO32DLL",&hmod_so32dll))!=0) { + FatalError("Could not load module so32dll.dll, rc = %d. Error note %s\n",rc,faildata); + } + if ((rc = DosQueryProcAddr(hmod_so32dll, 0, "SELECT", (PPFN)&os2_tcp_select))!=0) { + FatalError("Could not query address of SELECT, rc = %d.\n",rc); + } + if ((rc = DosQueryProcAddr(hmod_so32dll, 0, "SO_CANCEL", (PPFN)&os2_so_cancel))!=0) { + FatalError("Could not query address of SO_CANCEL, rc = %d.\n",rc); + } + if ((rc = DosQueryProcAddr(hmod_so32dll, 0, "SOCK_ERRNO", (PPFN)&os2_sock_errno))!=0) { + FatalError("Could not query address of SOCK_ERRNO, rc = %d.\n",rc); + } + + /* Call these a first time to set the semaphore */ + xf86OsMouseEvents(); + xf86KbdEvents(); + + DosCreateEventSem(NULL, &hSocketSem,DC_SEM_SHARED,FALSE); + DosResetEventSem(hSocketSem,&postCount); + + DosCreateEventSem(NULL, &hActivateSocketSem, DC_SEM_SHARED, FALSE); + DosResetEventSem(hActivateSocketSem, &postCount); + + DosCreateEventSem(NULL, &hSwitchToSem, DC_SEM_SHARED, FALSE); + DosResetEventSem(hSwitchToSem, &postCount); + + Socket_Tid = _beginthread(os2SocketMonitorThread, NULL, 0x2000,(void *) NULL); + xf86Msg(X_INFO, + "Started Socket monitor thread, TID=%d\n",Socket_Tid); + + SelectMuxRecord[0].hsemCur = (HSEM)hMouseSem; + SelectMuxRecord[0].ulUser = MOUSE_SEM_KEY; + SelectMuxRecord[1].hsemCur = (HSEM)hKbdSem; + SelectMuxRecord[1].ulUser = KBD_SEM_KEY; + SelectMuxRecord[2].hsemCur = (HSEM)hPipeSem; + SelectMuxRecord[2].ulUser = PIPE_SEM_KEY; + SelectMuxRecord[3].hsemCur = (HSEM)hSocketSem; + SelectMuxRecord[3].ulUser = SOCKET_SEM_KEY; + SelectMuxRecord[4].hsemCur = (HSEM)hSwitchToSem; + SelectMuxRecord[4].ulUser = SWITCHTO_SEM_KEY; + + rc = DosCreateMuxWaitSem(NULL, &hSelectWait, 5, SelectMuxRecord, + DC_SEM_SHARED | DCMW_WAIT_ANY); + if (rc) { + xf86Msg(X_ERROR,"Could not create MuxWait semaphore, rc=%d\n",rc); + } + FirstTime = FALSE; + } + + rc = DosResetEventSem(hActivateSocketSem, &postCount); + /* Set up the time delay structs */ + + if (timeout!=NULL) { + timeout_ms=timeout->tv_sec*1000+timeout->tv_usec/1000; + } else { + timeout_ms=1000000; /* This should be large enough... */ + } + + /* Zero our local fd_masks */ + {FD_ZERO(&sd.read_copy);} + {FD_ZERO(&sd.write_copy);} + + /* Copy the masks for later use */ + if (readfds!=NULL) { XFD_COPYSET(readfds,&sd.read_copy); sd.have_read=TRUE; } + if (writefds!=NULL) {XFD_COPYSET(writefds,&sd.write_copy); sd.have_write=TRUE; } + + /* And zero the original masks */ + if (sd.have_read){ FD_ZERO(readfds); } + if (sd.have_write) {FD_ZERO(writefds); } + if (exceptfds != NULL) {FD_ZERO(exceptfds); } + + /* Now we parse the fd_sets passed to select and separate pipe/sockets */ + n = os2_parse_select(&sd,nfds); + + /* Now check if we have sockets ready! */ + + if (sd.socket_ntotal > 0) { + ns = os2_poll_sockets(&sd,readfds,writefds); + if (ns>0) { + ready_handles+=ns; + any_ready = TRUE; + } else if (ns == -1) { + return(-1); + } + } + + /* And pipes */ + + if (sd.pipe_ntotal > 0) { + np = os2_check_pipes(&sd,readfds,writefds); + if (np > 0) { + ready_handles+=np; + any_ready = TRUE; + } else if (np == -1) { + return(-1); + } + } + + /* And finally poll input devices */ + if(!os2MouseQueueQuery() || !os2KbdQueueQuery() ) any_ready = TRUE; + + if (xf86Info.vtRequestsPending) any_ready=TRUE; + + if (os2PopupErrorPending) + os2RecoverFromPopup(); + + if (!any_ready && timeout_ms) { + DosResetEventSem(hSocketSem,&postCount); + + /* Activate the socket thread */ + if (sd.socket_ntotal>0) { + rc = DosPostEventSem(hActivateSocketSem); + } + + rc = DosWaitMuxWaitSem(hSelectWait, timeout_ms, &semKey); + + /* If our socket monitor thread is still blocked in os2_tcp_select() + * we have to wake it up by calling os2_so_cancel(). + * After that, call os2_tcp_select() once more to get rid of + * error SOCEINTR (10004) + */ + if (sd.socket_ntotal>0) { + rc = DosQueryEventSem(hSocketSem, &postCount); + + if (postCount == 0) { /* os2_select still blocked */ + int i,f,g; + struct select_data *sd_ptr=&sd; + + if (sd.socket_nread > 0) { + for (i=0; i<sd.socket_nread; i++) { + f = g = sd_ptr->tcp_select_mask[i]; + os2_so_cancel(f); + os2_tcp_select(&g, 1, 0, 0, 0); /* get rid of error 10004 */ + } + } + if (sd.socket_nwrite > 0) { + for (i=sd.socket_nread; + i<sd.socket_nread+sd.socket_nwrite; + i++) { + f = g = sd_ptr->tcp_select_mask[i]; + os2_so_cancel(f); + os2_tcp_select(&g, 0, 1, 0, 0); /* get rid of error 10004 */ + } + } + } else { /* not blocked, something must be ready -> get it */ + ns = os2_poll_sockets(&sd,readfds,writefds); + if (ns>0) { + ready_handles+=ns; + } else if (ns == -1) { + return(-1); + } + } + } + if (sd.pipe_ntotal > 0) { + rc = DosQueryEventSem(hPipeSem,&postCount); + if (postCount > 0) { + np = os2_check_pipes(&sd,readfds,writefds); + if (np > 0) { + ready_handles+=np; + } else if (np == -1) { + return(-1); + } + } + } + } + /* The polling of sockets/pipe automatically set the proper bits */ + return (ready_handles); +} + + +int os2_parse_select(sd,nfds) + struct select_data *sd; + int nfds; +{ + int i; + /* First we determine up to which descriptor we need to check. */ + /* No need to check up to 256 if we don't have to (and usually we dont...)*/ + /* Note: stuff here is hardcoded for fd_sets which are int[8] as in EMX!!! */ + + if (nfds > sd->max_fds) { + for (i=0;i<((FD_SETSIZE+31)/32);i++) { + if (sd->read_copy.fds_bits[i] || + sd->write_copy.fds_bits[i]) + sd->max_fds=(i*32) +32; + } + } else { sd->max_fds = nfds; } + + /* Check if this is greater than specified in select() call */ + if(sd->max_fds > nfds) sd->max_fds = nfds; + + if (sd->have_read) { + for (i = 0; i < sd->max_fds; ++i) { + if (FD_ISSET (i, &sd->read_copy)) { + if(_files[i] & F_SOCKET) { + sd->tcp_select_mask[sd->socket_ntotal]=_getsockhandle(i); + sd->tcp_emx_handles[sd->socket_ntotal]=i; + sd->socket_ntotal++; sd->socket_nread++; + } else if (_files[i] & F_PIPE) { + sd -> pipe_ntotal++; + } + } + } + } + if (sd->have_write) { + for (i = 0; i < sd->max_fds; ++i) { + if (FD_ISSET (i, &sd->write_copy)) { + if (_files[i] & F_SOCKET) { + sd->tcp_select_mask[sd->socket_ntotal]=_getsockhandle(i); + sd->tcp_emx_handles[sd->socket_ntotal]=i; + sd->socket_ntotal++; sd->socket_nwrite++; + } else if (_files[i] & F_PIPE) { + sd -> pipe_ntotal++; + sd -> pipe_have_write=TRUE; + } + } + } + } + return(sd->socket_ntotal); +} + + +int os2_poll_sockets(sd,readfds,writefds) + struct select_data *sd; + fd_set *readfds,*writefds; +{ + int e,i; + int j,n; + + memcpy(sd->tcp_select_copy,sd->tcp_select_mask, + sd->socket_ntotal*sizeof(int)); + + e = os2_tcp_select(sd->tcp_select_copy,sd->socket_nread, + sd->socket_nwrite, 0, 0); + + if (e == 0) return(e); + + /* We have something ready? */ + if (e>0) { + j = 0; n = 0; + for (i = 0; i < sd->socket_nread; ++i, ++j) + if (sd->tcp_select_copy[j] != -1) { + FD_SET (sd->tcp_emx_handles[j], readfds); + n ++; + } + for (i = 0; i < sd->socket_nwrite; ++i, ++j) + if (sd->tcp_select_copy[j] != -1) { + FD_SET (sd->tcp_emx_handles[j], writefds); + n ++; + } + errno = 0; + + return n; + } + if (e<0) { + /*Error -- TODO */ + xf86Msg(X_ERROR,"Error in server select! sock_errno = %d\n",os2_sock_errno()); + errno = EBADF; + return (-1); + } +} + +/* Check to see if anything is ready on pipes */ + +int os2_check_pipes(sd,readfds,writefds) + struct select_data *sd; + fd_set *readfds,*writefds; +{ + int i,e; + ULONG ulPostCount; + PIPESEMSTATE pipeSemState[128]; + APIRET rc; + + e = 0; + rc = DosResetEventSem(hPipeSem,&ulPostCount); + rc = DosQueryNPipeSemState((HSEM) hPipeSem, (PPIPESEMSTATE)&pipeSemState, + sizeof(pipeSemState)); + if(rc) xf86Msg(X_ERROR,"SELECT: rc from QueryNPipeSem: %d\n",rc); + i=0; + while (pipeSemState[i].fStatus != 0) { +/* xf86Msg(X_INFO,"SELECT: sem entry, stat=%d, flag=%d, key=%d,avail=%d\n", + pipeSemState[i].fStatus,pipeSemState[i].fFlag,pipeSemState[i].usKey, + pipeSemState[i].usAvail); */ + if ((pipeSemState[i].fStatus == 1) && + (FD_ISSET(pipeSemState[i].usKey,&sd->read_copy))) { + FD_SET(pipeSemState[i].usKey,readfds); + e++; + } else if ((pipeSemState[i].fStatus == 2) && + (FD_ISSET(pipeSemState[i].usKey,&sd->write_copy))) { + FD_SET(pipeSemState[i].usKey,writefds); + e++; + } else if ((pipeSemState[i].fStatus == 3) && + ((FD_ISSET(pipeSemState[i].usKey,&sd->read_copy)) || + (FD_ISSET(pipeSemState[i].usKey,&sd->write_copy)) )) { + errno = EBADF; + /* xf86Msg(X_ERROR,"Pipe has closed down, fd=%d\n",pipeSemState[i].usKey); */ + return (-1); + } + i++; + } /* endwhile */ + + errno = 0; + return(e); +} + + +void os2SocketMonitorThread(void *arg) +{ + struct select_data *sd_ptr = &sd; + ULONG ulPostCount; + int e,rc; + + /* Make thread time critical */ + DosSetPriority(2L,3L,0L,0L); + + while (1) { + rc = DosWaitEventSem(hActivateSocketSem, SEM_INDEFINITE_WAIT); + if (rc != 0 ) + xf86Msg(X_ERROR,"Socket monitor: DosWaitEventSem(hActivateSocketSem..) returned %d\n",rc); + + rc = DosResetEventSem(hActivateSocketSem,&ulPostCount); + if (rc != 0 ) + xf86Msg(X_ERROR,"Socket monitor: DosResetEventSem(&hActivateSocketSem..) returned %d\n",rc); + + /* fg300104: + * The next line shouldn't be here, but the DosPostEventSem() + * below will return 299 from time to time under heavy load + */ +/* DosResetEventSem(hSocketSem,&ulPostCount);*/ + + memcpy(sd_ptr->tcp_select_monitor,sd_ptr->tcp_select_mask, + sd_ptr->socket_ntotal*sizeof(int)); + + /* call os2_select(), return only if either something is ready or + * os2_so_cancel() was called + */ + e = os2_tcp_select(sd_ptr->tcp_select_monitor, sd_ptr->socket_nread, + sd_ptr->socket_nwrite, 0, -1); + + if (e>0) { + rc = DosPostEventSem(hSocketSem); + if (rc != 0 ) + xf86Msg(X_ERROR,"Socket monitor: DosPostEventSem(hSocketSem..) returned %d\n",rc); + } else if (e<0) { + rc = os2_sock_errno(); + if (rc != 10004) + xf86Msg(X_ERROR,"Socket monitor: os2_select: sock_errno = %d\n",rc); + } + + rc = DosQueryEventSem(hevServerHasFocus, &ulPostCount); + + /* no need to rush while switched away */ + if ((rc==0) && (ulPostCount==0)) + rc == DosWaitEventSem(hevServerHasFocus,31L); + } +} + diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_select.h b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_select.h new file mode 100644 index 000000000..cb2291e09 --- /dev/null +++ b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_select.h @@ -0,0 +1,62 @@ +/* $XConsortium: os2_select.h /main/1 1996/05/13 16:38:30 kaleb $ */ +/* + * (c) Copyright 1996 by Sebastien Marineau + * <marineau@genie.uottawa.ca> + * + * 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 + * HOLGER VEIT 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 Sebastien Marineau shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Sebastien Marineau. + * + */ + +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_select.h,v 3.1 1996/12/27 07:04:31 dawes Exp $ */ + +/* Header file for os2_select.c */ + +#define MAX_TCP 256 + +#define MOUSE_SEM_KEY 0x0F01 +#define KBD_SEM_KEY 0x0F02 +#define PIPE_SEM_KEY 0x0F03 +#define SOCKET_SEM_KEY 0x0F04 +#define SWITCHTO_SEM_KEY 0x0F05 + + +struct select_data +{ + fd_set read_copy; + fd_set write_copy; + BOOL have_read; + BOOL have_write; + int tcp_select_mask[MAX_TCP]; + int tcp_emx_handles[MAX_TCP]; + int tcp_select_copy[MAX_TCP]; + int tcp_select_monitor[MAX_TCP]; + int socket_nread; + int socket_nwrite; + int socket_ntotal; + int pipe_ntotal; + int pipe_have_write; + int max_fds; +}; + + + diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_serial.c b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_serial.c new file mode 100644 index 000000000..6587b1bda --- /dev/null +++ b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_serial.c @@ -0,0 +1,517 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_serial.c,v 1.3 2000/04/05 18:13:53 dawes Exp $ */ +/* + * (c) Copyright 1999 by Holger Veit + * <Holger.Veit@gmd.de> + * + * 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 + * HOLGER VEIT 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 Holger Veit shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Holger Veit. + * + */ +/* $XConsortium$ */ + +#define I_NEED_OS2_H +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <X11/X.h> +#include <X11/Xmd.h> +#include "input.h" +#include "scrnintstr.h" + +#include "compiler.h" + +#define INCL_DOSDEVIOCTL +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +static int _set_baudrate(HFILE fd,int baud) +{ + USHORT br = baud; + ULONG plen; + return DosDevIOCtl(fd,IOCTL_ASYNC,ASYNC_SETBAUDRATE, + (PULONG)&br,sizeof(br),&plen,NULL,0,NULL); +} + +#pragma pack(1) +typedef struct _glinectl { + UCHAR databits; + UCHAR parity; + UCHAR stopbits; + UCHAR sendbrk; +} GLINECTL; +typedef struct _slinectl { + UCHAR databits; + UCHAR parity; + UCHAR stopbits; +} SLINECTL; + +#pragma pack() + +static int _get_linectrl(HFILE fd,GLINECTL* linectrl) +{ + ULONG dlen; + return DosDevIOCtl(fd,IOCTL_ASYNC,ASYNC_GETLINECTRL, + NULL,0,NULL,linectrl,sizeof(GLINECTL),&dlen); +} + +static int _set_linectl(HFILE fd,GLINECTL* linectl) +{ + ULONG plen; + return DosDevIOCtl(fd,IOCTL_ASYNC,ASYNC_SETLINECTRL, + (PULONG)&linectl,sizeof(SLINECTL),&plen,NULL,0,NULL); +} + +static int _get_dcb(HFILE fd,DCBINFO* dcb) { + + ULONG dlen; + return DosDevIOCtl(fd,IOCTL_ASYNC,ASYNC_GETDCBINFO, + NULL,0,NULL,(PULONG)dcb,sizeof(DCBINFO),&dlen); +} + +static int _set_dcb(HFILE fd,DCBINFO* dcb) +{ + ULONG plen; + return DosDevIOCtl(fd,IOCTL_ASYNC, ASYNC_SETDCBINFO, + (PULONG)dcb,sizeof(DCBINFO),&plen,NULL,0,NULL); +} + +#pragma pack(1) +typedef struct comsize { + USHORT nqueued; + USHORT qsize; +} COMSIZE; +#pragma pack() + +static int _get_nread(HFILE fd,ULONG* nread) +{ + ULONG dlen; + COMSIZE sz; + APIRET rc = DosDevIOCtl(fd,IOCTL_ASYNC,ASYNC_GETINQUECOUNT, + NULL, 0, NULL, sz,sizeof(COMSIZE),&dlen); + *nread = sz.nqueued; + return rc ? -1 : 0; +} + +int xf86OpenSerial (pointer options) +{ + APIRET rc; + HFILE fd, i; + ULONG action; + GLINECTL linectl; + + char* dev = xf86FindOptionValue (options, "Device"); + xf86MarkOptionUsedByName (options, "Device"); + if (!dev) { + xf86Msg (X_ERROR, "xf86OpenSerial: No Device specified.\n"); + return -1; + } + + rc = DosOpen(dev, &fd, &action, 0, FILE_NORMAL, FILE_OPEN, + OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE, NULL); + if (rc) { + xf86Msg (X_ERROR, + "xf86OpenSerial: Cannot open device %s, rc=%d.\n", + dev, rc); + return -1; + } + + /* check whether it is an async device */ + if (_get_linectrl(fd,&linectl)) { + xf86Msg (X_WARNING, + "xf86OpenSerial: Specified device %s is not a tty\n", + dev); + DosClose(fd); + return -1; + } + + /* set up default port parameters */ + _set_baudrate(fd, 9600); + + linectl.databits = 8; + linectl.parity = 0; + linectl.stopbits = 0; + _set_linectl(fd, &linectl); + + if (xf86SetSerial (fd, options) == -1) { + DosClose(fd); + return -1; + } + + return fd; +} + +int xf86SetSerial (int fd, pointer options) +{ + APIRET rc; + USHORT baud; + ULONG plen,dlen; + char *s; + + GLINECTL linectl; + DCBINFO dcb; + + if ((s = xf86FindOptionValue (options, "BaudRate"))) { + xf86MarkOptionUsedByName (options, "BaudRate"); + if ((rc = _set_baudrate(fd, atoi(s)))) { + xf86Msg (X_ERROR,"Set Baudrate: %s, rc=%d\n", s, rc); + return -1; + } + } + + /* get line parameters */ + if (DosDevIOCtl((HFILE)fd,IOCTL_ASYNC, ASYNC_GETLINECTRL, + NULL,0,NULL, + (PULONG)&linectl,sizeof(GLINECTL),&dlen)) return -1; + + if ((s = xf86FindOptionValue (options, "StopBits"))) { + xf86MarkOptionUsedByName (options, "StopBits"); + switch (atoi (s)) { + case 1: linectl.stopbits = 0; + break; + case 2: linectl.stopbits = 2; + break; + default: xf86Msg (X_ERROR, + "Invalid Option StopBits value: %s\n", s); + return -1; + } + } + + if ((s = xf86FindOptionValue (options, "DataBits"))) { + int db; + xf86MarkOptionUsedByName (options, "DataBits"); + switch (db = atoi (s)) { + case 5: case 6: case 7: case 8: + linectl.databits = db; + break; + default: xf86Msg (X_ERROR, + "Invalid Option DataBits value: %s\n", s); + return -1; + } + } + + if ((s = xf86FindOptionValue (options, "Parity"))) { + xf86MarkOptionUsedByName (options, "Parity"); + if (xf86NameCmp (s, "Odd") == 0) + linectl.parity = 1; /* odd */ + else if (xf86NameCmp (s, "Even") == 0) + linectl.parity = 2; /* even */ + else if (xf86NameCmp (s, "None") == 0) + linectl.parity = 0; /* none */ + else { + xf86Msg (X_ERROR, + "Invalid Option Parity value: %s\n", s); + return -1; + } + } + + /* set line parameters */ + if (_set_linectl(fd,&linectl)) return -1; + + if (xf86FindOptionValue (options, "Vmin")) + xf86Msg (X_ERROR, "Vmin unsupported on this OS\n"); + + if (xf86FindOptionValue (options, "Vtime")) + xf86Msg (X_ERROR, "Vtime unsupported on this OS\n"); + + /* get device parameters */ + if (_get_dcb(fd,&dcb)) return -1; + + if ((s = xf86FindOptionValue (options, "FlowControl"))) { + xf86MarkOptionUsedByName (options, "FlowControl"); + if (xf86NameCmp (s, "XonXoff") == 0) + dcb.fbFlowReplace |= 0x03; + else if (xf86NameCmp (s, "None") == 0) + dcb.fbFlowReplace &= ~0x03; + else { + xf86Msg (X_ERROR, + "Invalid Option FlowControl value: %s\n", s); + return -1; + } + } + + if ((s = xf86FindOptionValue (options, "ClearDTR"))) { + dcb.fbCtlHndShake &= ~0x03; /* DTR=0 */ + xf86MarkOptionUsedByName (options, "ClearDTR"); + } + + if ((s = xf86FindOptionValue (options, "ClearRTS"))) { + dcb.fbFlowReplace &= ~0xc0; /* RTS=0 */ + xf86MarkOptionUsedByName (options, "ClearRTS"); + } + + /* set device parameters */ + return _set_dcb(fd,&dcb) ? -1 : 0; +} + +int xf86ReadSerial (int fd, void *buf, int count) +{ + ULONG nread,nq; + APIRET rc; + + /* emulate non-blocking read */ + if (_get_nread((HFILE)fd,&nq)) return -1; + if (nq==0) return 0; + if (nq < count) count = nq; + + rc = DosRead((HFILE)fd,(PVOID)buf,(ULONG)count,&nread); + return rc ? -1 : (int)nread; +} + +int xf86WriteSerial (int fd, const void *buf, int count) +{ + ULONG nwrite; + APIRET rc = DosWrite((HFILE)fd,(PVOID)buf,(ULONG)count,&nwrite); + return rc ? -1 : (int)nwrite; +} + +int xf86CloseSerial (int fd) +{ + APIRET rc = DosClose((HFILE)fd); + return rc ? -1 : 0; +} + +int xf86WaitForInput (int fd, int timeout) +{ + APIRET rc; + ULONG dlen,nq; + + do { + if (_get_nread((HFILE)fd,&nq)) return -1; + if (nq) return 1; + + DosSleep(10); + timeout -= 10000; /* 10000 usec */ + } while (timeout > 0); + + return 0; +} + +int xf86SerialSendBreak (int fd, int duration) +{ + USHORT data; + ULONG dlen; + APIRET rc; + rc = DosDevIOCtl((HFILE)fd,IOCTL_ASYNC,ASYNC_SETBREAKON, + NULL, 0, NULL, + &data, sizeof(data), &dlen); + if (rc) + return -1; + DosSleep(500); + + rc = DosDevIOCtl((HFILE)fd,IOCTL_ASYNC,ASYNC_SETBREAKOFF, + NULL, 0, NULL, + &data, sizeof(data), &dlen); + return rc ? -1 : 0; +} + +int xf86FlushInput(int fd) +{ + APIRET rc; + UCHAR buf; + ULONG nread,nq; + + if (_get_nread((HFILE)fd,&nq)) return -1; + + /* eat all chars in queue */ + while (nq) { + rc = DosRead((HFILE)fd,&buf,1,&nread); + if (rc) return -1; + nq--; + } + return 0; +} + +static struct states { + int xf; + int os; +} modemStates[] = { + { XF86_M_DTR, 0x01 }, + { XF86_M_RTS, 0x02 }, + { XF86_M_CTS, 0x10 }, + { XF86_M_DSR, 0x20 }, + { XF86_M_RNG, 0x40 }, + { XF86_M_CAR, 0x80 }, +}; + +static int numStates = sizeof(modemStates) / sizeof(modemStates[0]); + +static int +xf2osState(int state) +{ + int i; + int ret = 0; + + for (i = 0; i < numStates; i++) + if (state & modemStates[i].xf) + ret |= modemStates[i].os; + return ret; +} + +static int +os2xfState(int state) +{ + int i; + int ret = 0; + + for (i = 0; i < numStates; i++) + if (state & modemStates[i].os) + ret |= modemStates[i].xf; + return ret; +} + +static int +getOsStateMask(void) +{ + int i; + int ret = 0; + for (i = 0; i < numStates; i++) + ret |= modemStates[i].os; + return ret; +} + +static int osStateMask = 0; + +static +int _get_modem_state(int fd,ULONG* state) +{ + ULONG state1,len; + + if (DosDevIOCtl((HFILE)fd,IOCTL_ASYNC,ASYNC_GETMODEMOUTPUT, + NULL,0,NULL, state, sizeof(BYTE), &len) != 0 || + DosDevIOCtl((HFILE)fd,IOCTL_ASYNC,ASYNC_GETMODEMINPUT, + NULL,0,NULL, &state1, sizeof(BYTE), &len) != 0) + return -1; + *state |= state1; + *state &= 0xff; + return 0; +} + +static +int _set_modem_state(int fd,ULONG state,ULONG mask) +{ + int len; + struct { + BYTE onmask; + BYTE offmask; + } modemctrl; + modemctrl.onmask = state; + modemctrl.offmask = mask; + + if (DosDevIOCtl((HFILE)fd,IOCTL_ASYNC,ASYNC_SETMODEMCTRL, + NULL,0,NULL, (PULONG)&modemctrl, sizeof(modemctrl), &len) != 0) + return -1; + else + return 0; +} + +int +xf86SetSerialModemState(int fd, int state) +{ + ULONG s; + + if (fd < 0) + return -1; + + /* Don't try to set parameters for non-tty devices. */ + if (!isatty(fd)) + return 0; + + if (!osStateMask) + osStateMask = getOsStateMask(); + + state = xf2osState(state); + + if (_get_modem_state(fd,&s) != 0) + return -1; + + s &= ~osStateMask; + s |= state; + + return _set_modem_state(fd,s,0x03); +} + +int +xf86GetSerialModemState(int fd) +{ + ULONG s; + + if (fd < 0) + return -1; + + /* Don't try to set parameters for non-tty devices. */ + if (!isatty(fd)) + return 0; + + if (_get_modem_state(fd,&s) != 0) + return -1; + + return os2xfState(s); +} + +int +xf86SerialModemSetBits(int fd, int bits) +{ + int ret; + int s; + + if (fd < 0) + return -1; + + /* Don't try to set parameters for non-tty devices. */ + if (!isatty(fd)) + return 0; + + s = xf2osState(bits); + return _set_modem_state(fd,s,0x03); +} + +int +xf86SerialModemClearBits(int fd, int bits) +{ + int ret; + int s; + + if (fd < 0) + return -1; + + /* Don't try to set parameters for non-tty devices. */ + if (!isatty(fd)) + return 0; + + s = xf2osState(bits); + return _set_modem_state(fd, 0, ~s & 0xff); +} + +int +xf86SetSerialSpeed (int fd, int speed) +{ + if (fd < 0) + return -1; + + /* Don't try to set parameters for non-tty devices. */ + if (!isatty(fd)) + return 0; + + return _set_baudrate(fd,speed); +} diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_stubs.c b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_stubs.c new file mode 100644 index 000000000..727a605d1 --- /dev/null +++ b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_stubs.c @@ -0,0 +1,403 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_stubs.c,v 3.4 2002/05/31 18:46:02 dawes Exp $ */ +/* + * (c) Copyright 1996 by Holger Veit + * <Holger.Veit@gmd.de> + * + * 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 + * HOLGER VEIT 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 Holger Veit shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Holger Veit. + * + */ +/* $XConsortium: os2_stubs.c /main/3 1996/10/27 11:48:58 kaleb $ */ + +#define I_NEED_OS2_H +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <X11/X.h> +#include <X11/Xpoll.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/time.h> + +/* This is there to resolve a symbol in Xvfb + * this version is somewhat crippled compared to the one in os2_io.c + */ +#ifdef OS2NULLSELECT + +/* This below implements select() for calls in xnest. It has been */ +/* somewhat optimized for improved performance, but assumes a few */ +/* things so it cannot be used as a general select. */ + +#include <sys/select.h> +#include <sys/errno.h> +#define INCL_DOSSEMAPHORES +#define INCL_DOSNPIPES +#define INCL_DOSMISC +#define INCL_DOSMODULEMGR +#undef BOOL +#undef BYTE +#include <os2.h> + +HEV hPipeSem; +HMODULE hmod_so32dll; +static int (*os2_tcp_select)(int*,int,int,int,long); +ULONG os2_get_sys_millis(); +extern int _files[]; + +#define MAX_TCP 256 +/* These lifted from sys/emx.h. Change if that changes there! */ +#define F_SOCKET 0x10000000 +#define F_PIPE 0x20000000 + +struct select_data +{ + fd_set read_copy; + fd_set write_copy; + BOOL have_read; + BOOL have_write; + int tcp_select_mask[MAX_TCP]; + int tcp_emx_handles[MAX_TCP]; + int tcp_select_copy[MAX_TCP]; + int socket_nread; + int socket_nwrite; + int socket_ntotal; + int pipe_ntotal; + int pipe_have_write; + int max_fds; +}; + +int os2PseudoSelect(int nfds, fd_set *readfds, fd_set *writefds, + fd_set *exceptfds, struct timeval *timeout) +{ +static BOOL FirstTime=TRUE; +static haveTCPIP=TRUE; +ULONG timeout_ms; +ULONG postCount, start_millis,now_millis; +char faildata[16]; +struct select_data sd; +BOOL any_ready; +int np,ns, i,ready_handles,n; +APIRET rc; + +sd.have_read=FALSE; sd.have_write=FALSE; +sd.socket_nread=0; sd.socket_nwrite=0; sd.socket_ntotal=0; +sd.max_fds=31; ready_handles=0; any_ready=FALSE; +sd.pipe_ntotal=0; sd.pipe_have_write=FALSE; + +if(FirstTime){ + /* First load the so32dll.dll module and get a pointer to the SELECT function */ + + if((rc=DosLoadModule(faildata,sizeof(faildata),"SO32DLL",&hmod_so32dll))!=0){ + fprintf(stderr, "Could not load module so32dll.dll, rc = %d. Error note %s\n",rc,faildata); + haveTCPIP=FALSE; + } + if((rc = DosQueryProcAddr(hmod_so32dll, 0, "SELECT", (PPFN)&os2_tcp_select))!=0){ + fprintf(stderr, "Could not query address of SELECT, rc = %d.\n",rc); + haveTCPIP=FALSE; + } + /* Call these a first time to set the semaphore */ + /* rc = DosCreateEventSem(NULL, &hPipeSem, DC_SEM_SHARED, FALSE); + if(rc) { + fprintf(stderr, "Could not create event semaphore, rc=%d\n",rc); + return(-1); + } + rc = DosResetEventSem(hPipeSem, &postCount); */ /* Done in xtrans code for servers*/ + + /*fprintf(stderr, "Client select() done first-time stuff, sem handle %d.\n",hPipeSem);*/ + + FirstTime = FALSE; +} + +/* Set up the time delay structs */ + + if(timeout!=NULL) { + timeout_ms=timeout->tv_sec*1000+timeout->tv_usec/1000; + } + else { timeout_ms=1000000; } /* This should be large enough... */ + if(timeout_ms>0) start_millis=os2_get_sys_millis(); + +/* Copy the masks */ + {FD_ZERO(&sd.read_copy);} + {FD_ZERO(&sd.write_copy);} + if(readfds!=NULL){ XFD_COPYSET(readfds,&sd.read_copy); sd.have_read=TRUE;} + if(writefds!=NULL) {XFD_COPYSET(writefds,&sd.write_copy);sd.have_write=TRUE;} + +/* And zero the original masks */ + if(sd.have_read){ FD_ZERO(readfds);} + if(sd.have_write) {FD_ZERO(writefds);} + if(exceptfds != NULL) {FD_ZERO(exceptfds);} + +/* Now we parse the fd_sets passed to select and separate pipe/sockets */ + n = os2_parse_select(&sd,nfds); + if(n == -1) { + errno = EBADF; + return (-1); + } + +/* Now we have three cases: either we have sockets, pipes, or both */ +/* We handle all three cases differently to optimize things */ + +/* Case 1: only pipes! */ + if((sd.pipe_ntotal >0) && (!sd.socket_ntotal)){ + np = os2_check_pipes(&sd,readfds,writefds); + if(np > 0){ + return (np); + } + else if (np == -1) { return(-1); } + while(!any_ready){ + rc = DosWaitEventSem(hPipeSem, 1L); + /* if(rc) fprintf(stderr,"Sem-wait timeout, rc = %d\n",rc); */ + if(rc == 640) { + return(0); + } + if((rc != 0) && (rc != 95)) {errno= EBADF; return(-1);} + np = os2_check_pipes(&sd,readfds,writefds); + if (np > 0){ + return(np); + } + else if (np < 0){ return(-1); } + } + } + +/* Case 2: only sockets. Just let the os/2 tcp select do the work */ + if((sd.socket_ntotal > 0) && (!sd.pipe_ntotal)){ + ns = os2_check_sockets(&sd, readfds, writefds, timeout_ms); + return (ns); + } + +/* Case 3: combination of both */ + if((sd.socket_ntotal > 0) && (sd.pipe_ntotal)){ + np = os2_check_pipes(&sd,readfds,writefds); + if(np > 0){ + any_ready=TRUE; + ready_handles += np; + } + else if (np == -1) { return(-1); } + + ns = os2_check_sockets(&sd,readfds,writefds, 0); + if(ns>0){ + ready_handles+=ns; + any_ready = TRUE; + } + else if (ns == -1) {return(-1);} + + while (!any_ready && timeout_ms){ + + rc = DosWaitEventSem(hPipeSem, 1L); + if (rc=640) return(0); + if(rc == 0){ + np = os2_check_pipes(&sd,readfds,writefds); + if(np > 0){ + ready_handles+=np; + any_ready = TRUE; + } + else if (np == -1) { + return(-1); } + } + + ns = os2_check_sockets(&sd,readfds,writefds,exceptfds, 0); + if(ns>0){ + ready_handles+=ns; + any_ready = TRUE; + } + else if (ns == -1) {return(-1);} + + if (i%8 == 0) { + now_millis = os2_get_sys_millis(); + if((now_millis-start_millis) > timeout_ms) timeout_ms = 0; + } + i++; + } + } + +return(ready_handles); +} + + +ULONG os2_get_sys_millis() +{ + APIRET rc; + ULONG milli; + + rc = DosQuerySysInfo(14, 14, &milli, sizeof(milli)); + if(rc) { + fprintf(stderr,"Bad return code querying the millisecond counter! rc=%d\n",rc); + return(0); + } + return(milli); +} + +int os2_parse_select(sd,nfds) +struct select_data *sd; +int nfds; +{ + int i; + APIRET rc; +/* First we determine up to which descriptor we need to check. */ +/* No need to check up to 256 if we don't have to (and usually we dont...)*/ +/* Note: stuff here is hardcoded for fd_sets which are int[8] as in EMX! */ + + if(nfds > sd->max_fds){ + for(i=0;i<((FD_SETSIZE+31)/32);i++){ + if(sd->read_copy.fds_bits[i] || + sd->write_copy.fds_bits[i]) + sd->max_fds=(i*32) +32; + } + } + else { sd->max_fds = nfds; } +/* Check if result is greater than specified in select() call */ + if(sd->max_fds > nfds) sd->max_fds = nfds; + + if (sd->have_read) + { + for (i = 0; i < sd->max_fds; ++i) { + if (FD_ISSET (i, &sd->read_copy)){ + if(_files[i] & F_SOCKET) + { + sd->tcp_select_mask[sd->socket_ntotal]=_getsockhandle(i); + sd->tcp_emx_handles[sd->socket_ntotal]=i; + sd->socket_ntotal++; sd->socket_nread++; + } + else if (_files[i] & F_PIPE) + { + sd -> pipe_ntotal++; + /* rc = DosSetNPipeSem((HPIPE)i, (HSEM) hPipeSem, i); + if(rc) { fprintf(stderr,"Error SETNPIPE rc = %d\n",rc); return -1;} */ + } + } + } + } + + if (sd->have_write) + { + for (i = 0; i < sd->max_fds; ++i) { + if (FD_ISSET (i, &sd->write_copy)){ + if(_files[i] & F_SOCKET) + { + sd->tcp_select_mask[sd->socket_ntotal]=_getsockhandle(i); + sd->tcp_emx_handles[sd->socket_ntotal]=i; + sd->socket_ntotal++; sd->socket_nwrite++; + } + else if (_files[i] & F_PIPE) + { + sd -> pipe_ntotal++; + /* rc = DosSetNPipeSem((HPIPE)i, (HSEM) hPipeSem, i); + if(rc) { fprintf(stderr,"Error SETNPIPE rc = %d\n",rc); return -1;} */ + sd -> pipe_have_write=TRUE; + } + } + } + } + + +return(sd->socket_ntotal); +} + + +int os2_check_sockets(sd,readfds,writefds) +struct select_data *sd; +fd_set *readfds,*writefds; +{ + int e,i; + int j,n; + memcpy(sd->tcp_select_copy,sd->tcp_select_mask, + sd->socket_ntotal*sizeof(int)); + + e = os2_tcp_select(sd->tcp_select_copy,sd->socket_nread, + sd->socket_nwrite, 0, 0); + + if(e == 0) return(e); +/* We have something ready? */ + if(e>0){ + j = 0; n = 0; + for (i = 0; i < sd->socket_nread; ++i, ++j) + if (sd->tcp_select_copy[j] != -1) + { + FD_SET (sd->tcp_emx_handles[j], readfds); + n ++; + } + for (i = 0; i < sd->socket_nwrite; ++i, ++j) + if (sd->tcp_select_copy[j] != -1) + { + FD_SET (sd->tcp_emx_handles[j], writefds); + n ++; + } + errno = 0; + + return n; + } + if(e<0){ + /*Error -- TODO. EBADF is a good choice for now. */ + fprintf(stderr,"Error in server select! e=%d\n",e); + errno = EBADF; + return (-1); + } + } + +/* Check to see if anything is ready on pipes */ + +int os2_check_pipes(sd,readfds,writefds) +struct select_data *sd; +fd_set *readfds,*writefds; +{ +int i,e; +ULONG ulPostCount; +PIPESEMSTATE pipeSemState[128]; +APIRET rc; + e = 0; + rc = DosResetEventSem(hPipeSem,&ulPostCount); + rc = DosQueryNPipeSemState((HSEM) hPipeSem, (PPIPESEMSTATE)&pipeSemState, + sizeof(pipeSemState)); + if(rc) fprintf(stderr,"SELECT: rc from QueryNPipeSem: %d\n",rc); + i=0; + while (pipeSemState[i].fStatus != 0) { + /*fprintf(stderr,"SELECT: sem entry, stat=%d, flag=%d, key=%d,avail=%d\n", + pipeSemState[i].fStatus,pipeSemState[i].fFlag,pipeSemState[i].usKey, + pipeSemState[i].usAvail); */ + if((pipeSemState[i].fStatus == 1) && + (FD_ISSET(pipeSemState[i].usKey,&sd->read_copy))){ + FD_SET(pipeSemState[i].usKey,readfds); + e++; + } + else if((pipeSemState[i].fStatus == 2) && + (FD_ISSET(pipeSemState[i].usKey,&sd->write_copy))){ + FD_SET(pipeSemState[i].usKey,writefds); + e++; + } + else if( (pipeSemState[i].fStatus == 3) && + ( (FD_ISSET(pipeSemState[i].usKey,&sd->read_copy)) || + (FD_ISSET(pipeSemState[i].usKey,&sd->write_copy)) )){ + errno = EBADF; + /* fprintf(stderr,"Pipe has closed down, fd=%d\n",pipeSemState[i].usKey); */ + return (-1); + } + i++; + } /* endwhile */ + /*fprintf(stderr,"Done listing pipe sem entries, total %d entries, total ready entries %d\n",i,e);*/ +errno = 0; +return(e); +} + +#endif diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_video.c b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_video.c new file mode 100644 index 000000000..c45b3165e --- /dev/null +++ b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_video.c @@ -0,0 +1,241 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_video.c,v 3.15 2002/05/31 18:46:02 dawes Exp $ */ +/* + * (c) Copyright 1994,1999 by Holger Veit + * <Holger.Veit@gmd.de> + * Modified 1996 by Sebastien Marineau <marineau@genie.uottawa.ca> + * + * 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 + * HOLGER VEIT 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 Holger Veit shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Holger Veit. + * + */ +/* $XConsortium: os2_video.c /main/8 1996/10/27 11:49:02 kaleb $ */ + +#define I_NEED_OS2_H +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <X11/X.h> +#include "input.h" +#include "scrnintstr.h" + +#define INCL_DOSFILEMGR +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" +#include "xf86OSpriv.h" + +#include "compiler.h" + +/***************************************************************************/ +/* Video Memory Mapping helper functions */ +/***************************************************************************/ + +/* This section uses the xf86sup.sys driver developed for xfree86. + * The driver allows mapping of physical memory + * You must install it with a line DEVICE=path\xf86sup.sys in config.sys. + */ + +#define LOWORD(X) ((X) & 0xffff) +#define HIWORD(X) ((X) >> 16) + +static HFILE mapdev = -1; +static ULONG stored_virt_addr; +static char* mappath = "\\DEV\\PMAP$"; +static HFILE open_mmap() +{ + APIRET rc; + ULONG action; + + if (mapdev != -1) + return mapdev; + + rc = DosOpen((PSZ)mappath, (PHFILE)&mapdev, (PULONG)&action, + (ULONG)0, FILE_SYSTEM, FILE_OPEN, + OPEN_SHARE_DENYNONE|OPEN_FLAGS_NOINHERIT|OPEN_ACCESS_READONLY, + (ULONG)0); + if (rc!=0) { + mapdev = -1; } + else { + /* fg030203: ask for driver version of xf86sup.sys; + no output prior to version 1.539 */ + struct { + ULONG magic; + ULONG drvtype; + ULONG version; + } drvid; + ULONG dlen = sizeof(drvid); + if ((rc=DosDevIOCtl(mapdev, (ULONG)0x76, (ULONG)0x61, + (PVOID)NULL, (ULONG)0, (PULONG)NULL, + (PVOID)&drvid, (ULONG)dlen, (PULONG)&dlen))==0) { + xf86Msg(X_INFO,"PMAP$: driver version = %x.%x\n", + HIWORD(drvid.version), + LOWORD(drvid.version)); + } + } + return mapdev; +} + +static void close_mmap() +{ + if (mapdev != -1) + DosClose(mapdev); + mapdev = -1; +} + +/* this structure is used as a parameter packet for the direct access + * ioctl of pmap$ + */ + +/* Changed here for structure of driver PMAP$ */ + +typedef struct{ + ULONG addr; + ULONG size; +} DIOParPkt; + +/* This is the data packet for the mapping function */ + +typedef struct { + ULONG addr; + USHORT sel; +} DIODtaPkt; + +/***************************************************************************/ +/* Video Memory Mapping section */ +/***************************************************************************/ + +/* ARGSUSED */ +static pointer +mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags) +{ + DIOParPkt par; + ULONG plen; + DIODtaPkt dta; + ULONG dlen; + static BOOL ErrRedir = FALSE; + APIRET rc; + + par.addr = (ULONG)Base; + par.size = (ULONG)Size; + plen = sizeof(par); + dlen = sizeof(dta); + + open_mmap(); + if (mapdev == -1) + FatalError("mapVidMem: install DEVICE=path\\XF86SUP.SYS!"); + + if ((rc=DosDevIOCtl(mapdev, (ULONG)0x76, (ULONG)0x44, + (PVOID)&par, (ULONG)plen, (PULONG)&plen, + (PVOID)&dta, (ULONG)dlen, (PULONG)&dlen)) == 0) { + xf86Msg(X_INFO,"mapVidMem succeeded: (ScreenNum=%d, Base=0x%x, Size=0x%x, vaddr=0x%x)\n", + ScreenNum, Base, Size, dta.addr); + + if (dlen==sizeof(dta)) { + return (pointer)dta.addr; + } + /*else fail*/ + } + + /* fail */ + FatalError("mapVidMem FAILED!!: rc = %d (ScreenNum=%d, Base=0x%x, Size=0x%x, return len=%d, vaddr=0x%x, sel=0x%x)\n", + rc, ScreenNum, Base, Size, dlen, dta.addr, dta.sel); + return (pointer)0; +} + +/* ARGSUSED */ +static void +unmapVidMem(int ScreenNum, pointer Base, unsigned long Size) +{ + DIOParPkt par; + ULONG plen,vmaddr; + APIRET rc; +/* We need here the VIRTADDR for unmapping, not the physical address */ +/* This should be taken care of either here by keeping track of allocated */ +/* pointers, but this is also already done in the driver... Thus it would */ +/* be a waste to do this tracking twice. Can this be changed when the fn. */ +/* is called? This would require tracking this function in all servers, */ +/* and changing it appropriately to call this with the virtual adress */ +/* If the above mapping function is only called once, then we can store */ +/* the virtual adress and use it here.... */ + + par.addr = (ULONG)Base; + par.size = 0xffffffff; /* This is the virtual address parameter. Set this to ignore */ + plen = sizeof(par); + + if (mapdev != -1) + rc = DosDevIOCtl(mapdev, (ULONG)0x76, (ULONG)0x45, + (PVOID)&par, (ULONG)plen, (PULONG)&plen, + &vmaddr, sizeof(ULONG), &plen); + if (!rc) { + xf86Msg(X_INFO,"unmapVidMem: Unmap phys memory at virtual address 0x%x\n", + vmaddr); + } + else { + xf86Msg(X_ERROR,"unmapVidMem: Unmap phys memory at base 0x%x, virtual address 0x%x, rc=%d\n", + Base,vmaddr,rc); + } +/* Now if more than one region has been allocated and we close the driver, + * the other pointers will immediately become invalid. We avoid closing + * driver for now, but this should be fixed for server exit + */ + + /* close_mmap(); */ +} + +/***************************************************************************/ +/* Interrupt Handling section */ +/***************************************************************************/ + +Bool xf86DisableInterrupts() +{ + /* allow interrupt disabling but check for side-effects. + * Not a good policy on OS/2... + */ + asm ("cli"); + return TRUE; +} + +void xf86EnableInterrupts() +{ + /*Reenable*/ + asm ("sti"); +} + +/***************************************************************************/ +/* Initialize video memory */ +/***************************************************************************/ + +void +xf86OSInitVidMem(VidMemInfoPtr pVidMem) +{ + pVidMem->linearSupported = TRUE; + pVidMem->mapMem = mapVidMem; + pVidMem->unmapMem = unmapVidMem; +#if 0 + pVidMem->mapMemSparse = 0; + pVidMem->unmapMemSparse = 0; +#endif + pVidMem->setWC = 0; /* no MTRR support */ + pVidMem->undoWC = 0; + pVidMem->initialised = TRUE; +} |