aboutsummaryrefslogtreecommitdiff
path: root/src/glut/dos/PC_HW/pc_mouse.c
diff options
context:
space:
mode:
authorftrapero <frantracer@gmail.com>2017-06-27 12:08:38 +0200
committerftrapero <frantracer@gmail.com>2017-06-27 12:08:38 +0200
commit663631725ee2d633d9ec5821cd48953ffd188d00 (patch)
tree6d5cd671dd0fd27072661ab83a43f650295a980d /src/glut/dos/PC_HW/pc_mouse.c
downloadnx-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.c293
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");