jehanne: draft ioctl handling of TIOCGWINSZ and TIOCSWINSZ
This commit is contained in:
parent
5d3bb3fd38
commit
4fa1ec95ac
|
@ -17,13 +17,98 @@
|
|||
*/
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <envvars.h>
|
||||
#include <posix.h>
|
||||
#include <reent.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <errno.h>
|
||||
|
||||
void
|
||||
tty_getsize(struct winsize *size)
|
||||
{
|
||||
char *var;
|
||||
|
||||
var = jehanne_getenv("LINES");
|
||||
if(var != nil){
|
||||
size->ws_row = (unsigned short)atoi(var);
|
||||
free(var);
|
||||
} else {
|
||||
size->ws_row = 0;
|
||||
}
|
||||
var = jehanne_getenv("COLS");
|
||||
if(var != nil){
|
||||
size->ws_col = (unsigned short)atoi(var);
|
||||
free(var);
|
||||
} else {
|
||||
size->ws_row = 0;
|
||||
}
|
||||
var = jehanne_getenv("XPIXELS");
|
||||
if(var != nil){
|
||||
size->ws_xpixel = (unsigned short)atoi(var);
|
||||
free(var);
|
||||
} else {
|
||||
size->ws_row = 0;
|
||||
}
|
||||
var = jehanne_getenv("YPIXELS");
|
||||
if(var != nil){
|
||||
size->ws_ypixel = (unsigned short)atoi(var);
|
||||
free(var);
|
||||
} else {
|
||||
size->ws_row = 0;
|
||||
}
|
||||
}
|
||||
int
|
||||
tty_setsize(struct winsize *size)
|
||||
{
|
||||
int fd, i, s, w, h;
|
||||
char buf[64];
|
||||
struct winsize old;
|
||||
|
||||
if(size->ws_xpixel && size->ws_ypixel){
|
||||
PixelSized:
|
||||
fd = open("/dev/wctl", OWRITE);
|
||||
if(fd < 0)
|
||||
return 0;
|
||||
i = snprint(buf, sizeof(buf), "resize -dx %su -dy %su", size->ws_xpixel, size->ws_ypixel);
|
||||
write(fd, buf, i);
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
if(size->ws_row && size->ws_col){
|
||||
tty_getsize(&old);
|
||||
s = old.ws_xpixel / old.ws_col;
|
||||
size->ws_xpixel = (s + 1)*size->ws_col;
|
||||
s = old.ws_ypixel / old.ws_row;
|
||||
size->ws_ypixel = (s + 1)*size->ws_row;
|
||||
goto PixelSized;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int
|
||||
ioctl(int fd, int request, ...)
|
||||
{
|
||||
va_list ap;
|
||||
void *parg;
|
||||
|
||||
int *errnop = &_REENT->_errno;
|
||||
if(!POSIX_isatty(errnop, fd))
|
||||
return -1;
|
||||
|
||||
va_start(ap, request);
|
||||
switch(request){
|
||||
case TIOCGWINSZ:
|
||||
parg = va_arg(ap, void*);
|
||||
tty_getsize(parg);
|
||||
break;
|
||||
case TIOCSWINSZ:
|
||||
parg = va_arg(ap, void*);
|
||||
if(!tty_setsize(parg))
|
||||
*errnop = EPERM;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
va_end(ap);
|
||||
// blatant lie
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,17 @@
|
|||
#ifndef _SYS_IOCTL_H
|
||||
#define _SYS_IOCTL_H
|
||||
|
||||
#define TIOCGWINSZ 1
|
||||
#define TIOCSWINSZ 2
|
||||
|
||||
struct winsize {
|
||||
unsigned short ws_row;
|
||||
unsigned short ws_col;
|
||||
unsigned short ws_xpixel; /* unused */
|
||||
unsigned short ws_ypixel; /* unused */
|
||||
};
|
||||
|
||||
|
||||
int ioctl(int fd, int request, ...);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue