From d92a13968a1ffa7e335ce7f5b25ffff5b1923df4 Mon Sep 17 00:00:00 2001 From: Stas Sergeev Date: Fri, 30 Aug 2024 21:00:53 +0300 Subject: [PATCH] started adding clipboard support --- 32/Makefile | 2 +- src/Makefile | 2 +- src/clip.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/clip.h | 7 +++ src/command.c | 18 ++++++++ 5 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 src/clip.c create mode 100644 src/clip.h diff --git a/32/Makefile b/32/Makefile index 37fa827..85cb464 100644 --- a/32/Makefile +++ b/32/Makefile @@ -12,7 +12,7 @@ C_OPT += -march=i386 LINK_OPT = SRCS = $(SRCDIR)/command.c $(SRCDIR)/cmdbuf.c $(SRCDIR)/ms.c \ $(SRCDIR)/env.c $(SRCDIR)/psp.c $(SRCDIR)/umb.c $(SRCDIR)/ae0x.c \ - $(SRCDIR)/compl.c memmem.c fmemcpy.c findclos.c + $(SRCDIR)/compl.c $(SRCDIR)/clip.c memmem.c fmemcpy.c findclos.c ASSRCS = $(SRCDIR)/asm.S $(SRCDIR)/int23.S $(SRCDIR)/int0.S $(SRCDIR)/mouse.S OBJS = $(notdir $(SRCS:.c=.o)) $(notdir $(ASSRCS:.S=.o)) CMD = comcom32.exe diff --git a/src/Makefile b/src/Makefile index 32df4eb..353ed5a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,7 +2,7 @@ PREFIX ?= /usr/local DATADIR ?= $(PREFIX)/share/comcom64 CFLAGS = -Wall -Os -Wmissing-declarations -Wwrite-strings \ -ggdb3 -Wunused -Wmissing-prototypes -SOURCES = command.c cmdbuf.c mouse.c env.c psp.c umb.c ae0x.c compl.c \ +SOURCES = command.c cmdbuf.c mouse.c env.c psp.c umb.c ae0x.c compl.c clip.c \ thunks_a.c thunks_c.c HEADERS = ae0x.h cmdbuf.h compl.h psp.h command.h env.h mouse.h umb.h \ glob_asm.h asm.h diff --git a/src/clip.c b/src/clip.c new file mode 100644 index 0000000..dc6937e --- /dev/null +++ b/src/clip.c @@ -0,0 +1,124 @@ +/* + * comcom64 - 64bit command.com + * clip.c: winoldap clipboard support + * Copyright (C) 2024 @stsp + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "clip.h" + +#define CF 1 + +static int clip_open(void) +{ + __dpmi_regs r = {}; + + r.d.eax = 0x1701; + __dpmi_int(0x2f, &r); + if ((r.x.flags & CF) || r.x.ax != 0x3244) // check dosemu2 extension + return -1; + return r.x.ax; +} + +static void clip_close(void) +{ + __dpmi_regs r = {}; + + r.d.eax = 0x1708; + __dpmi_int(0x2f, &r); +} + +static unsigned clip_avail(int type) +{ + __dpmi_regs r = {}; + + r.d.eax = 0x1704; + r.d.edx = type; + __dpmi_int(0x2f, &r); + return ((r.x.dx << 16) | r.x.ax); +} + +int clip_read(int type, void (*cbk)(const char *buf, int len)) +{ + __dpmi_regs r = {}; + int rc; + int ret = 0; + unsigned avail; + + rc = clip_open(); + if (rc == -1) + return rc; + avail = clip_avail(type); + while (avail > 0) { + char buf[0x10000]; + uint16_t todo = (avail < 0xffff ? avail : 0xffff); + r.d.eax = 0x1705; + r.d.edx = type; + r.d.edi = rc; // enable dosemu2 extension + r.d.ecx = todo; + r.x.es = __tb_segment; + r.d.ebx = __tb_offset; + __dpmi_int(0x2f, &r); + if ((r.x.flags & CF) || r.x.ax != todo) { + ret = -1; + break; + } + dosmemget(__tb, todo, buf); + cbk(buf, todo); + ret += todo; + avail -= todo; + } + clip_close(); + return ret; +} + +int clip_write(int type, int (*cbk)(char *buf, int len)) +{ + __dpmi_regs r = {}; + int rc; + int ret = 0; + char buf[0x10000]; + int todo; + + rc = clip_open(); + if (rc == -1) + return rc; + while ((todo = cbk(buf, 0xffff)) > 0) { + r.d.eax = 0x1703; + r.d.edx = type; + r.d.ecx = todo; + r.x.es = __tb_segment; + r.d.ebx = __tb_offset; + dosmemput(buf, todo, __tb); + __dpmi_int(0x2f, &r); + if ((r.x.flags & CF) || r.x.ax == 0) { + ret = -1; + break; + } + ret += todo; + } + if (todo == -1) + ret = -1; + clip_close(); + return ret; +} diff --git a/src/clip.h b/src/clip.h new file mode 100644 index 0000000..039d23c --- /dev/null +++ b/src/clip.h @@ -0,0 +1,7 @@ +#ifndef CLIP_H +#define CLIP_H + +int clip_read(int type, void (*cbk)(const char *buf, int len)); +int clip_write(int type, int (*cbk)(char *buf, int len)); + +#endif diff --git a/src/command.c b/src/command.c index b953bcf..2f578ce 100644 --- a/src/command.c +++ b/src/command.c @@ -88,6 +88,7 @@ #include "umb.h" #include "ae0x.h" #include "compl.h" +#include "clip.h" #include "command.h" /* @@ -189,6 +190,7 @@ static void perform_break(const char *arg); static void perform_call(const char *arg); static void perform_cd(const char *arg); static void perform_choice(const char *arg); +static void perform_clip(const char *arg); static void perform_cls(const char *arg); static void perform_copy(const char *arg); static void perform_ctty(const char *arg); @@ -241,6 +243,7 @@ struct built_in_cmd cmd_table[] = {"cd", perform_cd, "", "change directory"}, {"chdir", perform_cd, "", "change directory"}, {"choice", perform_choice, "", "choice prompt sets ERRORLEVEL"}, + {"clip", perform_clip, "", "clipboard operations"}, {"cls", perform_cls, "", "clear screen"}, {"copy", perform_copy, "", "copy file"}, {"ctty", perform_ctty, "", "change tty"}, @@ -4017,6 +4020,21 @@ static void perform_ver(const char *arg) } } +static void cl_write(const char *buf, int len) + { + write(STDOUT_FILENO, buf, len); + } + +static void perform_clip(const char *arg) + { + int rc = clip_read(7, cl_write); + if (rc == -1) + { + cprintf("clipboard read failed\r\n"); + return; + } + } + static void perform_cls(const char *arg) { clrscr();