static void vcons_copyrows(void *cookie, int srcrow, int dstrow, int nrows) { struct rasops_info *ri = cookie; struct vcons_screen *scr = ri->ri_hw; vcons_copyrows_buffer(cookie, srcrow, dstrow, nrows); #if defined(VCONS_DRAW_INTR) if (scr->scr_vd->use_intr) return; #endif vcons_lock(scr); if (SCREEN_IS_VISIBLE(scr) && SCREEN_CAN_DRAW(scr)) { scr->scr_vd->copyrows(cookie, srcrow, dstrow, nrows); #if defined(VCONS_DRAW_INTR) vcons_invalidate_cache(scr->scr_vd); #endif } vcons_unlock(scr); }
int vcons_init_screen(struct vcons_data *vd, struct vcons_screen *scr, int existing, long *defattr) { struct rasops_info *ri = &scr->scr_ri; int cnt, i; #ifdef VCONS_DRAW_INTR int size; #endif scr->scr_cookie = vd->cookie; scr->scr_vd = scr->scr_origvd = vd; scr->scr_busy = 0; /* * call the driver-supplied init_screen function which is expected * to set up rasops_info, override cursor() and probably others */ vd->init_screen(vd->cookie, scr, existing, defattr); /* * save the non virtual console aware rasops and replace them with * our wrappers */ vd->eraserows = ri->ri_ops.eraserows; vd->erasecols = ri->ri_ops.erasecols; vd->putchar = ri->ri_ops.putchar; vd->cursor = ri->ri_ops.cursor; if (scr->scr_flags & VCONS_NO_COPYCOLS) { vd->copycols = vcons_copycols_noread; } else { vd->copycols = ri->ri_ops.copycols; } if (scr->scr_flags & VCONS_NO_COPYROWS) { vd->copyrows = vcons_copyrows_noread; } else { vd->copyrows = ri->ri_ops.copyrows; } ri->ri_ops.eraserows = vcons_eraserows; ri->ri_ops.erasecols = vcons_erasecols; ri->ri_ops.putchar = vcons_putchar; ri->ri_ops.cursor = vcons_cursor; ri->ri_ops.copycols = vcons_copycols; ri->ri_ops.copyrows = vcons_copyrows; ri->ri_hw = scr; /* * we allocate both chars and attributes in one chunk, attributes first * because they have the (potentially) bigger alignment */ #ifdef WSDISPLAY_SCROLLSUPPORT cnt = (ri->ri_rows + WSDISPLAY_SCROLLBACK_LINES) * ri->ri_cols; scr->scr_lines_in_buffer = WSDISPLAY_SCROLLBACK_LINES; scr->scr_current_line = 0; scr->scr_line_wanted = 0; scr->scr_offset_to_zero = ri->ri_cols * WSDISPLAY_SCROLLBACK_LINES; scr->scr_current_offset = scr->scr_offset_to_zero; #else cnt = ri->ri_rows * ri->ri_cols; #endif scr->scr_attrs = (long *)malloc(cnt * (sizeof(long) + sizeof(uint32_t)), M_DEVBUF, M_WAITOK); if (scr->scr_attrs == NULL) return ENOMEM; scr->scr_chars = (uint32_t *)&scr->scr_attrs[cnt]; ri->ri_ops.allocattr(ri, WS_DEFAULT_FG, WS_DEFAULT_BG, 0, defattr); scr->scr_defattr = *defattr; /* * fill the attribute buffer with *defattr, chars with 0x20 * since we don't know if the driver tries to mimic firmware output or * reset everything we do nothing to VRAM here, any driver that feels * the need to clear screen or something will have to do it on its own * Additional screens will start out in the background anyway so * cleaning or not only really affects the initial console screen */ for (i = 0; i < cnt; i++) { scr->scr_attrs[i] = *defattr; scr->scr_chars[i] = 0x20; } #ifdef VCONS_DRAW_INTR size = ri->ri_cols * ri->ri_rows; if (size > vd->cells) { if (vd->chars != NULL) free(vd->chars, M_DEVBUF); if (vd->attrs != NULL) free(vd->attrs, M_DEVBUF); vd->cells = size; vd->chars = malloc(size * sizeof(uint32_t), M_DEVBUF, M_WAITOK|M_ZERO); vd->attrs = malloc(size * sizeof(long), M_DEVBUF, M_WAITOK|M_ZERO); vcons_invalidate_cache(vd); } #endif if(vd->active == NULL) { vd->active = scr; SCREEN_VISIBLE(scr); } if (existing) { SCREEN_VISIBLE(scr); vd->active = scr; } else { SCREEN_INVISIBLE(scr); } LIST_INSERT_HEAD(&vd->screens, scr, next); return 0; }