1 /* $NetBSD: wsfontdev.c,v 1.19 2021/04/24 00:15:37 macallan Exp $ */ 2 3 /* 4 * Copyright (c) 2001 5 * Matthias Drochner. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions, and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __KERNEL_RCSID(0, "$NetBSD: wsfontdev.c,v 1.19 2021/04/24 00:15:37 macallan Exp $"); 31 32 #include <sys/param.h> 33 #include <sys/systm.h> 34 #include <sys/conf.h> 35 #include <sys/ioctl.h> 36 #include <sys/malloc.h> 37 #include <sys/event.h> 38 39 #include <dev/wsfont/wsfont.h> 40 #include <dev/wscons/wsconsio.h> /* XXX */ 41 42 #include "ioconf.h" 43 44 #ifdef WSFONT_DEBUG 45 #define DPRINTF printf 46 #else 47 #define DPRINTF while (0) printf 48 #endif 49 static int wsfont_isopen; 50 51 52 void 53 wsfontattach(int n) 54 { 55 56 wsfont_init(); 57 } 58 59 static int 60 wsfontopen(dev_t dev, int flag, int mode, 61 struct lwp *l) 62 { 63 64 if (wsfont_isopen) 65 return (EBUSY); 66 wsfont_isopen = 1; 67 return (0); 68 } 69 70 static int 71 wsfontclose(dev_t dev, int flag, int mode, 72 struct lwp *l) 73 { 74 75 wsfont_isopen = 0; 76 return (0); 77 } 78 79 static void 80 fontmatchfunc(struct wsdisplay_font *f, void *cookie, int fontcookie) 81 { 82 struct wsdisplayio_fontinfo *fi = cookie; 83 struct wsdisplayio_fontdesc fd; 84 int offset; 85 86 DPRINTF("%s %dx%d\n", f->name, f->fontwidth, f->fontheight); 87 if (fi->fi_fonts != NULL && fi->fi_buffersize > 0) { 88 memset(&fd, 0, sizeof(fd)); 89 strncpy(fd.fd_name, f->name, sizeof(fd.fd_name) - 1); 90 fd.fd_width = f->fontwidth; 91 fd.fd_height = f->fontheight; 92 offset = sizeof(struct wsdisplayio_fontdesc) * (fi->fi_numentries + 1); 93 if (offset > fi->fi_buffersize) { 94 fi->fi_fonts = NULL; 95 } else 96 copyout(&fd, &fi->fi_fonts[fi->fi_numentries], 97 sizeof(struct wsdisplayio_fontdesc)); 98 } 99 fi->fi_numentries++; 100 } 101 102 static int 103 wsdisplayio_listfonts(struct wsdisplayio_fontinfo *f) 104 { 105 void *addr = f->fi_fonts; 106 DPRINTF("%s: %d %d\n", __func__, f->fi_buffersize, f->fi_numentries); 107 f->fi_numentries = 0; 108 wsfont_walk(fontmatchfunc, f); 109 /* check if we ran out of buffer space */ 110 if (f->fi_fonts == NULL && addr != NULL) return ENOMEM; 111 return 0; 112 } 113 114 static int 115 wsfontioctl(dev_t dev, u_long cmd, void *data, int flag, 116 struct lwp *l) 117 { 118 char nbuf[64]; 119 void *buf; 120 int res; 121 122 switch (cmd) { 123 case WSDISPLAYIO_LDFONT: 124 #define d ((struct wsdisplay_font *)data) 125 if (d->name) { 126 res = copyinstr(d->name, nbuf, sizeof(nbuf), 0); 127 if (res) 128 return (res); 129 d->name = nbuf; 130 } else 131 d->name = "loaded"; /* ??? */ 132 buf = malloc(d->fontheight * d->stride * d->numchars, 133 M_DEVBUF, M_WAITOK); 134 res = copyin(d->data, buf, 135 d->fontheight * d->stride * d->numchars); 136 if (res) { 137 free(buf, M_DEVBUF); 138 return (res); 139 } 140 d->data = buf; 141 res = wsfont_add(d, 1); 142 free(buf, M_DEVBUF); 143 #undef d 144 return (res); 145 case WSDISPLAYIO_LISTFONTS: 146 return wsdisplayio_listfonts(data); 147 default: 148 return (EINVAL); 149 } 150 } 151 152 const struct cdevsw wsfont_cdevsw = { 153 .d_open = wsfontopen, 154 .d_close = wsfontclose, 155 .d_read = noread, 156 .d_write = nowrite, 157 .d_ioctl = wsfontioctl, 158 .d_stop = nostop, 159 .d_tty = notty, 160 .d_poll = nopoll, 161 .d_mmap = nommap, 162 .d_kqfilter = nokqfilter, 163 .d_discard = nodiscard, 164 .d_flag = D_OTHER 165 }; 166