📄 sg.c
字号:
*/ if( eqh->curs_pos.x != new_rep->dx || eqh->curs_pos.y != new_rep->dy) {/* * update cursor position */ eqh->curs_pos.x = new_rep->dx; eqh->curs_pos.y = new_rep->dy; if( tp->t_state & TS_ISOPEN ) { sgcursor = (struct color_cursor *) sgmap.cur; sgcursor->xpos = CURS_MIN_X + eqh->curs_pos.x; sgcursor->ypos = CURS_MIN_Y + eqh->curs_pos.y; } if (eqh->curs_pos.y < eqh->curs_box.bottom && eqh->curs_pos.y >= eqh->curs_box.top && eqh->curs_pos.x < eqh->curs_box.right && eqh->curs_pos.x >= eqh->curs_box.left) goto tbuttons; vep = PUTBEGIN(eqh); PUTEND(eqh); ++wakeup_flag; /* request a select wakeup call *//* Put event into queue *//* * The type should be "VSE_TMOTION" but, the X doesn't know this type, therefore * until X is fixed, we fake it to be "VSE_MMOTION". * */ vep->vse_type = VSE_MMOTION; vep->vse_device = VSE_TABLET; /* tablet */ vep->vse_direction = 0; vep->vse_x = eqh->curs_pos.x; vep->vse_y = eqh->curs_pos.y; vep->vse_key = 0; vep->vse_time = TOY; }/* * See if tablet buttons have changed. */tbuttons: new_switch = new_rep->state & 0x1e; old_switch = last_rep.state & 0x1e; temp = old_switch ^ new_switch; if( temp ) {/* event queue full? */ if (ISFULL(eqh) == TRUE) {/* mprintf("\nsg0: sgiint: event queue overflow");*/ return(0); } vep = PUTBEGIN(eqh); PUTEND(eqh); ++wakeup_flag; /* request a select wakeup call *//* put event into queue */ vep->vse_device = VSE_TABLET; /* tablet */ vep->vse_type = VSE_BUTTON; vep->vse_x = eqh->curs_pos.x; vep->vse_y = eqh->curs_pos.y; vep->vse_time = TOY;/* define the changed button and if up or down */ for (j = 1; j <= 0x10; j <<= 1) {/* check each button */ if (!(j & temp)) /* did this button change? */ continue; switch (j) { case T_RIGHT_BUTTON: vep->vse_key = VSE_T_RIGHT_BUTTON; break; case T_FRONT_BUTTON: vep->vse_key = VSE_T_FRONT_BUTTON; break; case T_BACK_BUTTON: vep->vse_key = VSE_T_BACK_BUTTON; break; case T_LEFT_BUTTON: vep->vse_key = VSE_T_LEFT_BUTTON; break; } if (new_switch & j) vep->vse_direction = VSE_KBTDOWN; else vep->vse_direction = VSE_KBTUP; }/* update the last report */ last_rep = current_rep; } } /* Pick up tablet input */ } /* While input available *//* * If we have proc waiting, and event has happened, wake him up */ if(rsel && wakeup_flag && sgflags.selmask & SEL_READ) { selwakeup(rsel,0); rsel = 0; sgflags.selmask &= ~SEL_READ; wakeup_flag = 0; } }/* * If the graphic device is not turned on, this is console input */ else {/* * Get a character from the keyboard. */ if (ch & 0100000) { data = ch & 0xff;/* * Check for various keyboard errors */ if( data == LK_POWER_ERROR || data == LK_KDOWN_ERROR || data == LK_INPUT_ERROR || data == LK_OUTPUT_ERROR) { mprintf("sg0: sgiint: Keyboard error, code = %x\n",data); return(0); } if( data < LK_LOWEST ) return(0);/* * See if its a state change key */ switch ( data ) { case LOCK: sg_keyboard.lock ^= 0xffff; /* toggle */ if( sg_keyboard.lock ) sg_key_out( LK_LED_ENABLE ); else sg_key_out( LK_LED_DISABLE ); sg_key_out( LED_3 ); return; case SHIFT: sg_keyboard.shift ^= 0xffff; return; case CNTRL: sg_keyboard.cntrl ^= 0xffff; return; case ALLUP: sg_keyboard.cntrl = sg_keyboard.shift = 0; return; case REPEAT: c = sg_keyboard.last; break; case HOLD:/* * "Hold Screen" key was pressed, we treat it as if ^s or ^q was typed. */ if (sg_keyboard.hold == 0) { if((tp->t_state & TS_TTSTOP) == 0) { c = q_key[CHAR_S]; sg_key_out( LK_LED_ENABLE ); sg_key_out( LED_4 ); sg_keyboard.hold = 1; } else c = q_key[CHAR_Q]; } else { c = q_key[CHAR_Q]; sg_key_out( LK_LED_DISABLE ); sg_key_out( LED_4 ); sg_keyboard.hold = 0; } if( c >= ' ' && c <= '~' ) c &= 0x1f; (*linesw[tp->t_line].l_rint)(c, tp); return; default:/* * Test for control characters. If set, see if the character * is elligible to become a control character. */ if( sg_keyboard.cntrl ) { c = q_key[ data ]; if( c >= ' ' && c <= '~' ) c &= 0x1f; else if (c >= 0xA1 && c <= 0xFE) c &= 0x9F; } else if( sg_keyboard.lock || sg_keyboard.shift ) c = q_shift_key[ data ]; else c = q_key[ data ]; break; } sg_keyboard.last = c;/* * Check for special function keys */ if( c & 0x100 ) { register char *string; string = q_special[ c & 0x7f ]; while( *string ) (*linesw[tp->t_line].l_rint)(*string++, tp); } else { /* Give the regular character to the user. */ if (tp->t_iflag & ISTRIP) /* Strip to 7 bits. */ c &= 0177; else { /* Take the full 8-bits */ /* * If ISTRIP is not set a valid character of 377 * is read as 0377,0377 to avoid ambiguity with * the PARMARK sequence. */ if ((c == 0377) && (tp->t_line == TERMIODISC) && (tp->t_iflag & PARMRK)) (*linesw[tp->t_line].l_rint)(0377,tp); } (*linesw[tp->t_line].l_rint)(c, tp); } if (sg_keyboard.hold &&((tp->t_state & TS_TTSTOP) == 0)) { sg_key_out( LK_LED_DISABLE ); sg_key_out( LED_4 ); sg_keyboard.hold = 0; } } } return(0);}/****************************************************************** ** ** ** Routine to start transmission. ** ** ** ******************************************************************/sgstart(tp) register struct tty *tp;{ register int unit, c; register struct tty *tp0; int s; unit = minor(tp->t_dev); tp0 = &sm_tty; unit &= 03; s = spl5();/* * If it's currently active, or delaying, no need to do anything. */ if (tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) goto out;/* * Display chars until the queue is empty, if the second subchannel is open * direct them there. Drop characters from any lines other than 0 on the floor. * TANDEM is set on second subchannel for flow control. */ while( tp->t_outq.c_cc ) { if (unit == 0) { /* console device */ if (tp0->t_state & TS_ISOPEN) { if (tp0->t_state & TS_TBLOCK) goto out; c = getc(&tp->t_outq); (*linesw[tp0->t_line].l_rint)(c, tp0); } else { c = getc(&tp->t_outq); sg_blitc((char)(c & 0xff)); } } else if (unit == 2) { /* sgscreen, do flow control */ c = getc(&tp->t_outq); if ((tp0->t_state&TS_TBLOCK) == 0) { tp = &ss_tty[0]; unit = minor(tp->t_dev); unit &= 3; continue; } else goto out; } else c = getc(&tp->t_outq); }/* * If there are sleepers, and output has drained below low * water mark, wake up the sleepers. */ if ( tp->t_outq.c_cc<=TTLOWAT(tp) ) if (tp->t_state&TS_ASLEEP){ tp->t_state &= ~TS_ASLEEP; wakeup((caddr_t)&tp->t_outq); } tp->t_state &= ~TS_BUSY;out: splx(s);}/****************************************************************** ** ** ** Routine to stop output on the graphic device, e.g. for ^S/^Q ** ** or output flush. ** ** ** ******************************************************************//*ARGSUSED*/sgstop(tp, flag) register struct tty *tp;{ register int s;/* * Block interrupts while modifying the state. */ s = spl5(); if (tp->t_state & TS_BUSY) if ((tp->t_state&TS_TTSTOP)==0) tp->t_state |= TS_FLUSH; else tp->t_state &= ~TS_BUSY; splx(s);}/****************************************************************** ** ** ** Routine to output a character to the screen ** ** ** ******************************************************************/sg_blitc( c )register u_char c;{ register struct adder *sgaddr; register struct color_cursor *sgcursor; register int i; register u_char savechar;/* * initialize ADDER */ sgaddr = (struct adder *) sgmap.adder; sgcursor = (struct color_cursor *) sgmap.cur; c &= 0xff; switch ( c ) { case '\t': /* tab */ for (i = 8 - ((cursor.x >> 3) & 0x07); i > 0; --i) { sg_blitc( ' ' ); } return(0); case '\r': /* return */ cursor.x = 0; if (!(sgflags.inuse & GRAPHIC_DEV)) sgcursor->xpos = CURS_MIN_X + cursor.x; return(0); case '\b': /* backspace */ if (cursor.x > 0) { cursor.x -= CHAR_WIDTH; sg_blitc( ' ' ); cursor.x -= CHAR_WIDTH; if (!(sgflags.inuse & GRAPHIC_DEV)) sgcursor->xpos = CURS_MIN_X + cursor.x; } return(0); case '\n': /* linefeed */ if ((cursor.y += CHAR_HEIGHT) > (MAX_CUR_Y - CHAR_HEIGHT)) { if (sg_mouseon == 1) cursor.y = 0; else { cursor.y -= CHAR_HEIGHT; sg_scroll_up(sgaddr); } } if (!(sgflags.inuse & GRAPHIC_DEV)) sgcursor->ypos = CURS_MIN_Y + cursor.y; return(0); default: /*---------------------------------------------------------- * Weed out unprintable characters. Printable characters fall * between space (0x20) and tilde (0x7E). For 8-bit support * another range of printable characters are those between * 0xA1 and 0xFD. */ if ((c < ' ') || (c > 0xFD) || (c < 0xA1 && c > '~')) return(0); }/* * setup VIPER operand control registers */ sg_write_id(sgaddr, CS_UPDATE_MASK, 0x0001); /* select plane #0 */ sg_write_id(sgaddr, SRC1_OCR_B, EXT_NONE | INT_SOURCE | ID | BAR_SHIFT_DELAY); sg_write_id(sgaddr, CS_UPDATE_MASK, 0x00FE); /* select other planes */ sg_write_id(sgaddr, SRC1_OCR_B, EXT_SOURCE | INT_NONE | NO_ID | BAR_SHIFT_DELAY); sg_write_id(sgaddr, CS_UPDATE_MASK, 0x00FF); /* select all planes */ sg_write_id(sgaddr, DST_OCR_B, EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY); sg_write_id(sgaddr, MASK_1, 0xFFFF); sg_write_id(sgaddr, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 1); sg_write_id(sgaddr, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0); sgaddr->x_clip_min = 0; sgaddr->x_clip_max = 1024; sgaddr->y_clip_min = 0; sgaddr->y_clip_max = 864;/* * load DESTINATION origin and vectors */ sgaddr->fast_dest_dy = 0; sgaddr->slow_dest_dx = 0; sgaddr->error_1 = 0; sgaddr->error_2 = 0; sgaddr->rasterop_mode = DST_WRITE_ENABLE | NORMAL; sg_wait_status(sgaddr, RASTEROP_COMPLETE); sgaddr->destination_x = cursor.x; sgaddr->fast_dest_dx = CHAR_WIDTH; sgaddr->destination_y = cursor.y; sgaddr->slow_dest_dy = CHAR_HEIGHT;/* * load SOURCE origin and vectors */ if (c > '~') { savechar = c; c -= 34; /* These are to skip the (32) 8-bit control chars. as well as DEL and 0xA0 which aren't printable */ } if ((c - ' ') > (CHARS - 1)) { mprintf("Invalid character (x)%x in sg_blitc\n",c); c = ' '; } /* X position is modulo the number of characters per line */ sgaddr->source_1_x = FONT_X + (((c - ' ') % (MAX_SCREEN_X/CHAR_WIDTH)) * CHAR_WIDTH); /* Point to either first or second row */ sgaddr-
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -