11.20Suwe/* $NetBSD: wsfontdev.c,v 1.20 2022/05/12 23:17:42 uwe Exp $ */ 21.1Sdrochner 31.1Sdrochner/* 41.1Sdrochner * Copyright (c) 2001 51.1Sdrochner * Matthias Drochner. All rights reserved. 61.1Sdrochner * 71.1Sdrochner * Redistribution and use in source and binary forms, with or without 81.1Sdrochner * modification, are permitted provided that the following conditions 91.1Sdrochner * are met: 101.1Sdrochner * 1. Redistributions of source code must retain the above copyright 111.1Sdrochner * notice, this list of conditions, and the following disclaimer. 121.1Sdrochner * 2. Redistributions in binary form must reproduce the above copyright 131.1Sdrochner * notice, this list of conditions and the following disclaimer in the 141.1Sdrochner * documentation and/or other materials provided with the distribution. 151.1Sdrochner * 161.1Sdrochner * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 171.1Sdrochner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 181.1Sdrochner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 191.1Sdrochner * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 201.1Sdrochner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 211.1Sdrochner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 221.1Sdrochner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 231.1Sdrochner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 241.1Sdrochner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 251.1Sdrochner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 261.1Sdrochner * SUCH DAMAGE. 271.1Sdrochner */ 281.3Slukem 291.3Slukem#include <sys/cdefs.h> 301.20Suwe__KERNEL_RCSID(0, "$NetBSD: wsfontdev.c,v 1.20 2022/05/12 23:17:42 uwe Exp $"); 311.1Sdrochner 321.1Sdrochner#include <sys/param.h> 331.1Sdrochner#include <sys/systm.h> 341.1Sdrochner#include <sys/conf.h> 351.20Suwe#include <sys/fcntl.h> 361.1Sdrochner#include <sys/ioctl.h> 371.1Sdrochner#include <sys/malloc.h> 381.6Sjdolecek#include <sys/event.h> 391.1Sdrochner 401.1Sdrochner#include <dev/wsfont/wsfont.h> 411.1Sdrochner#include <dev/wscons/wsconsio.h> /* XXX */ 421.1Sdrochner 431.17Schristos#include "ioconf.h" 441.4Sgehenna 451.19Smacallan#ifdef WSFONT_DEBUG 461.19Smacallan#define DPRINTF printf 471.19Smacallan#else 481.19Smacallan#define DPRINTF while (0) printf 491.19Smacallan#endif 501.1Sdrochnerstatic int wsfont_isopen; 511.1Sdrochner 521.19Smacallan 531.1Sdrochnervoid 541.13Schristoswsfontattach(int n) 551.1Sdrochner{ 561.1Sdrochner 571.1Sdrochner wsfont_init(); 581.1Sdrochner} 591.1Sdrochner 601.9Sthorpejstatic int 611.13Schristoswsfontopen(dev_t dev, int flag, int mode, 621.13Schristos struct lwp *l) 631.1Sdrochner{ 641.1Sdrochner 651.1Sdrochner if (wsfont_isopen) 661.1Sdrochner return (EBUSY); 671.1Sdrochner wsfont_isopen = 1; 681.1Sdrochner return (0); 691.1Sdrochner} 701.1Sdrochner 711.9Sthorpejstatic int 721.13Schristoswsfontclose(dev_t dev, int flag, int mode, 731.13Schristos struct lwp *l) 741.1Sdrochner{ 751.1Sdrochner 761.1Sdrochner wsfont_isopen = 0; 771.1Sdrochner return (0); 781.1Sdrochner} 791.1Sdrochner 801.19Smacallanstatic void 811.19Smacallanfontmatchfunc(struct wsdisplay_font *f, void *cookie, int fontcookie) 821.19Smacallan{ 831.19Smacallan struct wsdisplayio_fontinfo *fi = cookie; 841.19Smacallan struct wsdisplayio_fontdesc fd; 851.19Smacallan int offset; 861.19Smacallan 871.19Smacallan DPRINTF("%s %dx%d\n", f->name, f->fontwidth, f->fontheight); 881.19Smacallan if (fi->fi_fonts != NULL && fi->fi_buffersize > 0) { 891.19Smacallan memset(&fd, 0, sizeof(fd)); 901.19Smacallan strncpy(fd.fd_name, f->name, sizeof(fd.fd_name) - 1); 911.19Smacallan fd.fd_width = f->fontwidth; 921.19Smacallan fd.fd_height = f->fontheight; 931.19Smacallan offset = sizeof(struct wsdisplayio_fontdesc) * (fi->fi_numentries + 1); 941.19Smacallan if (offset > fi->fi_buffersize) { 951.19Smacallan fi->fi_fonts = NULL; 961.19Smacallan } else 971.19Smacallan copyout(&fd, &fi->fi_fonts[fi->fi_numentries], 981.19Smacallan sizeof(struct wsdisplayio_fontdesc)); 991.19Smacallan } 1001.19Smacallan fi->fi_numentries++; 1011.19Smacallan} 1021.19Smacallan 1031.19Smacallanstatic int 1041.19Smacallanwsdisplayio_listfonts(struct wsdisplayio_fontinfo *f) 1051.19Smacallan{ 1061.19Smacallan void *addr = f->fi_fonts; 1071.19Smacallan DPRINTF("%s: %d %d\n", __func__, f->fi_buffersize, f->fi_numentries); 1081.19Smacallan f->fi_numentries = 0; 1091.19Smacallan wsfont_walk(fontmatchfunc, f); 1101.19Smacallan /* check if we ran out of buffer space */ 1111.19Smacallan if (f->fi_fonts == NULL && addr != NULL) return ENOMEM; 1121.19Smacallan return 0; 1131.19Smacallan} 1141.19Smacallan 1151.9Sthorpejstatic int 1161.14Schristoswsfontioctl(dev_t dev, u_long cmd, void *data, int flag, 1171.13Schristos struct lwp *l) 1181.1Sdrochner{ 1191.18Smacallan char nbuf[64]; 1201.1Sdrochner void *buf; 1211.1Sdrochner int res; 1221.1Sdrochner 1231.1Sdrochner switch (cmd) { 1241.1Sdrochner case WSDISPLAYIO_LDFONT: 1251.1Sdrochner#define d ((struct wsdisplay_font *)data) 1261.20Suwe if ((flag & FWRITE) == 0) 1271.20Suwe return EPERM; 1281.20Suwe 1291.1Sdrochner if (d->name) { 1301.1Sdrochner res = copyinstr(d->name, nbuf, sizeof(nbuf), 0); 1311.1Sdrochner if (res) 1321.1Sdrochner return (res); 1331.1Sdrochner d->name = nbuf; 1341.1Sdrochner } else 1351.1Sdrochner d->name = "loaded"; /* ??? */ 1361.1Sdrochner buf = malloc(d->fontheight * d->stride * d->numchars, 1371.1Sdrochner M_DEVBUF, M_WAITOK); 1381.1Sdrochner res = copyin(d->data, buf, 1391.1Sdrochner d->fontheight * d->stride * d->numchars); 1401.1Sdrochner if (res) { 1411.1Sdrochner free(buf, M_DEVBUF); 1421.1Sdrochner return (res); 1431.1Sdrochner } 1441.1Sdrochner d->data = buf; 1451.1Sdrochner res = wsfont_add(d, 1); 1461.1Sdrochner free(buf, M_DEVBUF); 1471.1Sdrochner#undef d 1481.1Sdrochner return (res); 1491.19Smacallan case WSDISPLAYIO_LISTFONTS: 1501.19Smacallan return wsdisplayio_listfonts(data); 1511.1Sdrochner default: 1521.1Sdrochner return (EINVAL); 1531.1Sdrochner } 1541.1Sdrochner} 1551.9Sthorpej 1561.9Sthorpejconst struct cdevsw wsfont_cdevsw = { 1571.15Sdholland .d_open = wsfontopen, 1581.15Sdholland .d_close = wsfontclose, 1591.15Sdholland .d_read = noread, 1601.15Sdholland .d_write = nowrite, 1611.15Sdholland .d_ioctl = wsfontioctl, 1621.15Sdholland .d_stop = nostop, 1631.15Sdholland .d_tty = notty, 1641.15Sdholland .d_poll = nopoll, 1651.15Sdholland .d_mmap = nommap, 1661.15Sdholland .d_kqfilter = nokqfilter, 1671.16Sdholland .d_discard = nodiscard, 1681.15Sdholland .d_flag = D_OTHER 1691.9Sthorpej}; 170