📄 fb.c
字号:
oldSwitch = lastRep.state & 0x07; temp = oldSwitch ^ newSwitch; if (temp == 0) return; for (j = 1; j < 8; j <<= 1) { if ((j & temp) == 0) continue; /* * Check for room in the queue */ i = PM_EVROUND(fp->fbu->scrInfo.qe.eTail+1); if (i == fp->fbu->scrInfo.qe.eHead) return; /* * Put event into queue. */ eventPtr = &fp->fbu->events[fp->fbu->scrInfo.qe.eTail]; switch (j) { case RIGHT_BUTTON: eventPtr->key = EVENT_RIGHT_BUTTON; break; case MIDDLE_BUTTON: eventPtr->key = EVENT_MIDDLE_BUTTON; break; case LEFT_BUTTON: eventPtr->key = EVENT_LEFT_BUTTON; } if (newSwitch & j) eventPtr->type = BUTTON_DOWN_TYPE; else eventPtr->type = BUTTON_UP_TYPE; eventPtr->device = MOUSE_DEVICE; eventPtr->time = TO_MS(time); eventPtr->x = fp->fbu->scrInfo.mouse.x; eventPtr->y = fp->fbu->scrInfo.mouse.y; fp->fbu->scrInfo.qe.eTail = i; } selwakeup(&fp->selp); lastRep = *newRepPtr; fp->fbu->scrInfo.mswitches = newSwitch;}/* *---------------------------------------------------------------------- * * fbScroll -- * * Scroll the screen. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */voidfbScroll(fp) register struct pmax_fb *fp;{ register int *dest, *src; register int *end; register int temp0, temp1, temp2, temp3; register int i, scanInc, lineCount; int line; /* * If the mouse is on we don't scroll so that the bit map remains sane. */ if (fp->GraphicsOpen) { fp->row = 0; return; } /* * The following is an optimization to cause the scrolling * of text to be memory limited. Basically the writebuffer is * 4 words (32 bits ea.) long so to achieve maximum speed we * read and write in multiples of 4 words. We also limit the * size to be fp->fbu->scrInfo.max_col characters for more speed. */ if (fp->isMono) { lineCount = 5; line = 1920 * 2; scanInc = 44; } else { lineCount = 40; if (fp->fbu->scrInfo.max_x > 1024) { scanInc = 352; line = 1920 * 16; } else { scanInc = 96; line = 1920 * 8; } } src = (int *)(fp->fr_addr + line); dest = (int *)(fp->fr_addr); end = (int *)(fp->fr_addr + (68 * line) - line); do { i = 0; do { temp0 = src[0]; temp1 = src[1]; temp2 = src[2]; temp3 = src[3]; dest[0] = temp0; dest[1] = temp1; dest[2] = temp2; dest[3] = temp3; dest += 4; src += 4; i++; } while (i < lineCount); src += scanInc; dest += scanInc; } while (src < end); /* * Now zero out the last two lines */ bzero(fp->fr_addr + (fp->row * line), 3 * line);}/* *---------------------------------------------------------------------- * * fbPutc -- * * Write a character to the console. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */voidfbPutc(dev, c) dev_t dev; register int c;{ int s; if (cn_tab.cn_fb) { static int recurse; /* * We need to prevent recursion in case a printf to the * console happens at interrupt time but using splhigh() * all the time locks out interrupts too much. We simply * discard the character in this case and rely on the * console log buffer to save the message. */ if (recurse) return; recurse = 1; fbBlitc(c, cn_tab.cn_fb); recurse = 0; } else { s = splhigh(); (*callv->printf)("%c", c); splx(s); }}/* *---------------------------------------------------------------------- * * fbBlitc -- * * Write a character to the screen. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */voidfbBlitc(c, fp) register int c; register struct pmax_fb *fp;{ register char *bRow, *fRow; register int i; register int ote; int colMult = fp->isMono ? 1 : 8; if (fp->isMono) ote = 256; else ote = ((fp->fbu->scrInfo.max_x + 1023) / 1024) * 1024; c &= 0xff; switch (c) { case '\t': for (i = 8 - (fp->col & 0x7); i > 0; i--) fbBlitc(' ', fp); break; case '\r': fp->col = 0; break; case '\b': fp->col--; if (fp->col < 0) fp->col = 0; break; case '\n': if (fp->row + 1 >= fp->fbu->scrInfo.max_row) fbScroll(fp); else fp->row++; fp->col = 0; break; case '\007': (*fp->KBDPutc)(fp->kbddev, LK_RING_BELL); break; default: /* * 0xA1 to 0xFD are the printable characters added with 8-bit * support. */ if (c < ' ' || c > '~' && c < 0xA1 || c > 0xFD) break; /* * If the next character will wrap around then * increment fp->row counter or scroll screen. */ if (fp->col >= fp->fbu->scrInfo.max_col) { fp->col = 0; if (fp->row + 1 >= fp->fbu->scrInfo.max_row) fbScroll(fp); else fp->row++; } bRow = (char *)(fp->fr_addr + (fp->row * 15 & 0x3ff) * ote + fp->col * colMult); i = c - ' '; /* * This is to skip the (32) 8-bit * control chars, as well as DEL * and 0xA0 which aren't printable */ if (c > '~') i -= 34; i *= 15; fRow = (char *)((int)pmFont + i); /* inline expansion for speed */ if (fp->isMono) { *bRow = *fRow++; bRow += ote; *bRow = *fRow++; bRow += ote; *bRow = *fRow++; bRow += ote; *bRow = *fRow++; bRow += ote; *bRow = *fRow++; bRow += ote; *bRow = *fRow++; bRow += ote; *bRow = *fRow++; bRow += ote; *bRow = *fRow++; bRow += ote; *bRow = *fRow++; bRow += ote; *bRow = *fRow++; bRow += ote; *bRow = *fRow++; bRow += ote; *bRow = *fRow++; bRow += ote; *bRow = *fRow++; bRow += ote; *bRow = *fRow++; bRow += ote; *bRow = *fRow++; bRow += ote; } else { register int j; register unsigned int *pInt; pInt = (unsigned int *)bRow; for (j = 0; j < 15; j++) { /* * fontmaskBits converts a nibble * (4 bytes) to a long word * containing 4 pixels corresponding * to each bit in the nibble. Thus * we write two longwords for each * byte in font. * * Remember the font is 8 bits wide * and 15 bits high. * * We add 256/512 to the pointer to * point to the pixel on the * next scan line * directly below the current * pixel. */ pInt[0] = fontmaskBits[(*fRow) & 0xf]; pInt[1] = fontmaskBits[((*fRow) >> 4) & 0xf]; fRow++; if (fp->fbu->scrInfo.max_x > 1024) pInt += 512; else pInt += 256; } } fp->col++; /* increment column counter */ } if (!fp->GraphicsOpen) (*fp->posCursor)(fp->col * 8, fp->row * 15);}/* * ---------------------------------------------------------------------------- * * kbdMapChar -- * * Map characters from the keyboard to ASCII. Return -1 if there is * no valid mapping. * * Results: * None. * * Side effects: * Remember state of shift and control keys. * * ---------------------------------------------------------------------------- */kbdMapChar(cc) int cc;{ static u_char shiftDown; static u_char ctrlDown; static u_char lastChar; switch (cc) { case KEY_REPEAT: cc = lastChar; goto done; case KEY_UP: shiftDown = 0; ctrlDown = 0; return (-1); case KEY_SHIFT: case KEY_R_SHIFT: if (ctrlDown || shiftDown) shiftDown = 0; else shiftDown = 1; return (-1); case KEY_CONTROL: if (shiftDown || ctrlDown) ctrlDown = 0; else ctrlDown = 1; return (-1); case LK_POWER_ERROR: case LK_KDOWN_ERROR: case LK_INPUT_ERROR: case LK_OUTPUT_ERROR: log(LOG_WARNING, "lk201: keyboard error, code=%x\n", cc); return (-1); } if (shiftDown) cc = shiftedAscii[cc]; else cc = unshiftedAscii[cc]; if (cc >= KBD_NOKEY) { /* * A function key was typed - ignore it. */ return (-1); } if (cc >= 'a' && cc <= 'z') { if (ctrlDown) cc = cc - 'a' + '\1'; /* ^A */ else if (shiftDown) cc = cc - 'a' + 'A'; } else if (ctrlDown) { if (cc >= '[' && cc <= '_') cc = cc - '@'; else if (cc == ' ' || cc == '@') cc = '\0'; } lastChar = cc;done: return (cc);}/* * Initialize the Keyboard. */voidKBDReset(kbddev, putc) dev_t kbddev; void (*putc)();{ register int i; static int inKBDReset; if (inKBDReset) return; inKBDReset = 1; for (i = 0; i < sizeof(kbdInitString); i++) (*putc)(kbddev, (int)kbdInitString[i]); inKBDReset = 0;}/* * Initialize the mouse. */voidMouseInit(mdev, putc, getc) dev_t mdev; void (*putc)(); int (*getc)();{ int id_byte1, id_byte2, id_byte3, id_byte4; /* * Initialize the mouse. */ (*putc)(mdev, MOUSE_SELF_TEST); id_byte1 = (*getc)(mdev); if (id_byte1 < 0) { printf("MouseInit: Timeout on 1st byte of self-test report\n"); return; } id_byte2 = (*getc)(mdev); if (id_byte2 < 0) { printf("MouseInit: Timeout on 2nd byte of self-test report\n"); return; } id_byte3 = (*getc)(mdev); if (id_byte3 < 0) { printf("MouseInit: Timeout on 3rd byte of self-test report\n"); return; } id_byte4 = (*getc)(mdev); if (id_byte4 < 0) { printf("MouseInit: Timeout on 4th byte of self-test report\n"); return; } if ((id_byte2 & 0x0f) != 0x2) printf("MouseInit: We don't have a mouse!!!\n"); /* * For some reason, the mouse doesn't see this command if it comes * too soon after a self test. */ DELAY(100); (*putc)(mdev, MOUSE_INCREMENTAL);}/* * Get a character off of the keyboard. */intKBDGetc(){ register int c; for (;;) { c = (*cn_tab.cn_kbdgetc)(cn_tab.cn_dev); if (c == 0) return (-1); if ((c = kbdMapChar(c & 0xff)) >= 0) break; } return (c);}/* * Configure the keyboard/mouse based on machine type for turbochannel * display boards. */tb_kbdmouseconfig(fp) struct pmax_fb *fp;{ switch (pmax_boardtype) {#if NDC > 0 case DS_3MAX: fp->KBDPutc = dcPutc; fp->kbddev = makedev(DCDEV, DCKBD_PORT); break;#endif#if NSCC > 0 case DS_3MIN: case DS_3MAXPLUS: fp->KBDPutc = sccPutc; fp->kbddev = makedev(SCCDEV, SCCKBD_PORT); break;#endif#if NDTOP > 0 case DS_MAXINE: fp->KBDPutc = dtopKBDPutc; fp->kbddev = makedev(DTOPDEV, DTOPKBD_PORT); break;#endif default: printf("Can't configure keyboard/mouse\n"); return (1); }; return (0);}/* * Use vm_mmap() to map the frame buffer and shared data into the user's * address space. * Return errno if there was an error. */fbmmap(fp, dev, data, p) struct pmax_fb *fp; dev_t dev; caddr_t data; struct proc *p;{ int error; vm_offset_t addr; vm_size_t len; struct vnode vn; struct specinfo si; struct fbuaccess *fbp; len = pmax_round_page(((vm_offset_t)fp->fbu & PGOFSET) + sizeof(struct fbuaccess)) + pmax_round_page(fp->fr_size); addr = (vm_offset_t)0x20000000; /* XXX */ vn.v_type = VCHR; /* XXX */ vn.v_specinfo = &si; /* XXX */ vn.v_rdev = dev; /* XXX */ /* * Map the all the data the user needs access to into * user space. */ error = vm_mmap(&p->p_vmspace->vm_map, &addr, len, VM_PROT_ALL, VM_PROT_ALL, MAP_SHARED, (caddr_t)&vn, (vm_offset_t)0); if (error) return (error); fbp = (struct fbuaccess *)(addr + ((vm_offset_t)fp->fbu & PGOFSET)); *(PM_Info **)data = &fbp->scrInfo; fp->fbu->scrInfo.qe.events = fbp->events; fp->fbu->scrInfo.qe.tcs = fbp->tcs; fp->fbu->scrInfo.planemask = (char *)0; /* * Map the frame buffer into the user's address space. */ fp->fbu->scrInfo.bitmap = (char *)pmax_round_page(fbp + 1); return (0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -