diff options
author | ftrapero <frantracer@gmail.com> | 2017-06-27 12:08:38 +0200 |
---|---|---|
committer | ftrapero <frantracer@gmail.com> | 2017-06-27 12:08:38 +0200 |
commit | 663631725ee2d633d9ec5821cd48953ffd188d00 (patch) | |
tree | 6d5cd671dd0fd27072661ab83a43f650295a980d /src/glut/dos/PC_HW/pc_mouse.c | |
download | nx-libs-663631725ee2d633d9ec5821cd48953ffd188d00.tar.gz nx-libs-663631725ee2d633d9ec5821cd48953ffd188d00.tar.bz2 nx-libs-663631725ee2d633d9ec5821cd48953ffd188d00.zip |
Squashed 'nx-X11/extras/Mesa_6.4.2/' content from commit 475b1f7
git-subtree-dir: nx-X11/extras/Mesa_6.4.2
git-subtree-split: 475b1f7b56fa36ef4f3b22a749f88a98ddc0d502
Diffstat (limited to 'src/glut/dos/PC_HW/pc_mouse.c')
-rw-r--r-- | src/glut/dos/PC_HW/pc_mouse.c | 293 |
1 files changed, 293 insertions, 0 deletions
diff --git a/src/glut/dos/PC_HW/pc_mouse.c b/src/glut/dos/PC_HW/pc_mouse.c new file mode 100644 index 000000000..5bf99d367 --- /dev/null +++ b/src/glut/dos/PC_HW/pc_mouse.c @@ -0,0 +1,293 @@ +/* + * PC/HW routine collection v1.3 for DOS/DJGPP + * + * Copyright (C) 2002 - Daniel Borca + * Email : dborca@yahoo.com + * Web : http://www.geocities.com/dborca + */ + + +#include <dpmi.h> +#include <sys/exceptn.h> +#include <sys/segments.h> + +#include "pc_hw.h" + + +#define PC_CUTE_WHEEL 1 /* CuteMouse WheelAPI */ + +#define MOUSE_STACK_SIZE 16384 + +#define CLEAR_MICKEYS() \ + do { \ + __asm __volatile ("movw $0xb, %%ax; int $0x33":::"%eax", "%ecx", "%edx"); \ + ox = oy = 0; \ + } while (0) + +extern void mouse_wrap (void); +extern int mouse_wrap_end[]; + +static MFUNC mouse_func; +static long mouse_callback; +static __dpmi_regs mouse_regs; + +static volatile struct { + volatile int x, y, z, b; +} pc_mouse; + +static int minx = 0; +static int maxx = 319; +static int miny = 0; +static int maxy = 199; +static int minz = 0; +static int maxz = 255; + +static int sx = 2; +static int sy = 2; + +static int emulat3 = FALSE; + +static int ox, oy; + + +static void +mouse (__dpmi_regs *r) +{ + int nx = (signed short)r->x.si / sx; + int ny = (signed short)r->x.di / sy; + int dx = nx - ox; + int dy = ny - oy; +#if PC_CUTE_WHEEL + int dz = (signed char)r->h.bh; +#endif + ox = nx; + oy = ny; + + pc_mouse.b = r->h.bl; + pc_mouse.x = MID(minx, pc_mouse.x + dx, maxx); + pc_mouse.y = MID(miny, pc_mouse.y + dy, maxy); +#if PC_CUTE_WHEEL + pc_mouse.z = MID(minz, pc_mouse.z + dz, maxz); +#endif + + if (emulat3) { + if ((pc_mouse.b & 3) == 3) { + pc_mouse.b = 4; + } + } + + if (mouse_func) { + mouse_func(pc_mouse.x, pc_mouse.y, pc_mouse.z, pc_mouse.b); + } +} ENDOFUNC(mouse) + + +void +pc_remove_mouse (void) +{ + if (mouse_callback) { + pc_clexit(pc_remove_mouse); + __asm("\n\ + movl %%edx, %%ecx \n\ + shrl $16, %%ecx \n\ + movw $0x0304, %%ax \n\ + int $0x31 \n\ + movw $0x000c, %%ax \n\ + xorl %%ecx, %%ecx \n\ + int $0x33 \n\ + "::"d"(mouse_callback):"%eax", "%ecx"); + + mouse_callback = 0; + + free((void *)(mouse_wrap_end[0] - MOUSE_STACK_SIZE)); + } +} + + +int +pc_install_mouse (void) +{ + int buttons; + + /* fail if already call-backed */ + if (mouse_callback) { + return 0; + } + + /* reset mouse and get status */ + __asm("\n\ + xorl %%eax, %%eax \n\ + int $0x33 \n\ + andl %%ebx, %%eax \n\ + movl %%eax, %0 \n\ + ":"=g" (buttons)::"%eax", "%ebx"); + if (!buttons) { + return 0; + } + + /* lock wrapper */ + LOCKDATA(mouse_func); + LOCKDATA(mouse_callback); + LOCKDATA(mouse_regs); + LOCKDATA(pc_mouse); + LOCKDATA(minx); + LOCKDATA(maxx); + LOCKDATA(miny); + LOCKDATA(maxy); + LOCKDATA(minz); + LOCKDATA(maxz); + LOCKDATA(sx); + LOCKDATA(sy); + LOCKDATA(emulat3); + LOCKDATA(ox); + LOCKDATA(oy); + LOCKFUNC(mouse); + LOCKFUNC(mouse_wrap); + + mouse_wrap_end[1] = __djgpp_ds_alias; + /* grab a locked stack */ + if ((mouse_wrap_end[0] = (int)pc_malloc(MOUSE_STACK_SIZE)) == NULL) { + return 0; + } + + /* try to hook a call-back */ + __asm("\n\ + pushl %%ds \n\ + pushl %%es \n\ + movw $0x0303, %%ax \n\ + pushl %%ds \n\ + pushl %%cs \n\ + popl %%ds \n\ + popl %%es \n\ + int $0x31 \n\ + popl %%es \n\ + popl %%ds \n\ + jc 0f \n\ + shll $16, %%ecx \n\ + movw %%dx, %%cx \n\ + movl %%ecx, %0 \n\ + 0: \n\ + ":"=g"(mouse_callback) + :"S" (mouse_wrap), "D"(&mouse_regs) + :"%eax", "%ecx", "%edx"); + if (!mouse_callback) { + free((void *)mouse_wrap_end[0]); + return 0; + } + + /* adjust stack */ + mouse_wrap_end[0] += MOUSE_STACK_SIZE; + + /* install the handler */ + mouse_regs.x.ax = 0x000c; +#if PC_CUTE_WHEEL + mouse_regs.x.cx = 0x7f | 0x80; +#else + mouse_regs.x.cx = 0x7f; +#endif + mouse_regs.x.dx = mouse_callback & 0xffff; + mouse_regs.x.es = mouse_callback >> 16; + __dpmi_int(0x33, &mouse_regs); + + CLEAR_MICKEYS(); + + emulat3 = (buttons < 3); + pc_atexit(pc_remove_mouse); + return buttons; +} + + +MFUNC +pc_install_mouse_handler (MFUNC handler) +{ + MFUNC old; + + if (!mouse_callback && !pc_install_mouse()) { + return NULL; + } + + old = mouse_func; + mouse_func = handler; + return old; +} + + +void +pc_mouse_area (int x1, int y1, int x2, int y2) +{ + minx = x1; + maxx = x2; + miny = y1; + maxy = y2; +} + + +void +pc_mouse_speed (int xspeed, int yspeed) +{ + DISABLE(); + + sx = MAX(1, xspeed); + sy = MAX(1, yspeed); + + ENABLE(); +} + + +int +pc_query_mouse (int *x, int *y, int *z) +{ + *x = pc_mouse.x; + *y = pc_mouse.y; + *z = pc_mouse.z; + return pc_mouse.b; +} + + +void +pc_warp_mouse (int x, int y) +{ + CLEAR_MICKEYS(); + + pc_mouse.x = MID(minx, x, maxx); + pc_mouse.y = MID(miny, y, maxy); + + if (mouse_func) { + mouse_func(pc_mouse.x, pc_mouse.y, pc_mouse.z, pc_mouse.b); + } +} + + +/* Hack alert: + * `mouse_wrap_end' actually holds the + * address of stack in a safe data selector. + */ +__asm("\n\ + .text \n\ + .p2align 5,,31 \n\ + .global _mouse_wrap \n\ +_mouse_wrap: \n\ + cld \n\ + lodsl \n\ + movl %eax, %es:42(%edi) \n\ + addw $4, %es:46(%edi) \n\ + pushl %es \n\ + movl %ss, %ebx \n\ + movl %esp, %esi \n\ + lss %cs:_mouse_wrap_end, %esp\n\ + pushl %ss \n\ + pushl %ss \n\ + popl %es \n\ + popl %ds \n\ + movl ___djgpp_dos_sel, %fs \n\ + pushl %fs \n\ + popl %gs \n\ + pushl %edi \n\ + call _mouse \n\ + popl %edi \n\ + movl %ebx, %ss \n\ + movl %esi, %esp \n\ + popl %es \n\ + iret \n\ + .global _mouse_wrap_end \n\ +_mouse_wrap_end:.long 0, 0"); |