📄 pw_access.c
字号:
} pw->pw_clipdata->pwcd_lockcount = 1; /* Don't need screen access if batching */ if (pw->pw_clipdata->pwcd_batch_type != PW_NONE) return; /* * Make sure gp2 has correct colormap for 8-bit on 24-bit * frame buffer. This is a no-op for all other cases. * Sorta ugly but gets full binary backward compatibilty. */ pr_ioctl(pw->pw_pixrect, GP1IO_SCMAP, 0); winlock.wl_rect = *affected; /* Transform from pixwin to window coordinates */ winlock.wl_rect.r_left = PW_X_TO_WIN(pw, winlock.wl_rect.r_left); winlock.wl_rect.r_top = PW_Y_TO_WIN(pw, winlock.wl_rect.r_top); /* try to used the shared memory first */ if (!pw_shared_lock(pw, &winlock.wl_rect)) { /* * Transform coordinate systems if a region. * i.e. transform from region space to window space. */ if (pw->pw_clipdata->pwcd_regionrect) rect_passtoparent(pw->pw_clipdata->pwcd_regionrect->r_left, pw->pw_clipdata->pwcd_regionrect->r_top, &winlock.wl_rect); /* * Set lockcount before actually get lock so that reset knows that * it should unlock if called during the time that this ioctl is * happening. This is a race condition. * Extra unlocks are fairly harmless (unless you block). */ (void)werror(ioctl(pw->pw_clipdata->pwcd_windowfd, WINLOCKSCREEN, &winlock), WINLOCKSCREEN); if (pixwindebug) (void)werror(ioctl(pw->pw_clipdata->pwcd_windowfd, WINUNLOCKSCREEN, 0), WINUNLOCKSCREEN); if (pw->pw_clipdata->pwcd_clipid!=winlock.wl_clipid) { /* * Get new version of the clipping if out of date */ (void)pw_getclipping(pw); } } else { if (pixwindebug) (void)pw_shared_unlock(pw); } if (pw->pw_clipdata->pwcd_state == PWCD_SINGLERECT) { pw->pw_opshandle = (caddr_t) pw->pw_clipdata->pwcd_prsingle; pw->pw_ops = pw->pw_pixrect->pr_ops; pw->pw_opsx += pw->pw_clipdata->pwcd_clipping.rl_bound.r_left; pw->pw_opsy += pw->pw_clipdata->pwcd_clipping.rl_bound.r_top; } else if (pw->pw_clipdata->pwcd_state == PWCD_NULL) { pw->pw_ops = &pw_opsstd_null_lock; } return;}pwco_unlockstd(pw) register struct pixwin *pw;{ if (pw->pw_clipdata->pwcd_lockcount==0) return; if (pw->pw_clipdata->pwcd_lockcount==1) { /* Didn't get screen access if batching */ if (pw->pw_clipdata->pwcd_batch_type != PW_NONE) goto Done; /* try to used the shared memory first */ if (!pixwindebug && !pw_shared_unlock(pw)) (void)werror(ioctl(pw->pw_clipdata->pwcd_windowfd, WINUNLOCKSCREEN, 0), WINUNLOCKSCREEN); if ((pw->pw_clipdata->pwcd_state == PWCD_SINGLERECT) || (pw->pw_clipdata->pwcd_state == PWCD_NULL)) { pw->pw_opshandle = (caddr_t) pw; pw->pw_ops = &pw_opsstd; pw->pw_opsx = pw->pw_clipdata->pwcd_x_offset; pw->pw_opsy = pw->pw_clipdata->pwcd_y_offset; } }Done: pw->pw_clipdata->pwcd_lockcount--; return;}pwco_resetstd(pw) struct pixwin *pw;{ pwco_reinitclipping(pw); /* * Unlock */ while (pw->pw_clipdata->pwcd_lockcount) (void)pw_unlock(pw); return;}/*ARGSUSED*/pwco_getclippingstd(pw) struct pixwin *pw;{ /* * Standard is nop */}/* * Pixwin structure operations utilities */_pw_getclipping(pw, damaged) struct pixwin *pw; bool damaged;{ struct winclip winclip; /* * free existing clipping */ pwco_reinitclipping(pw); /* * Copy clipping data from kernel */ win_getwinclip(pw->pw_clipdata->pwcd_windowfd, damaged, &winclip, &pw->pw_clipdata->pwcd_clipping); pw->pw_clipdata->pwcd_clipid = winclip.wc_clipid; /* save the (left, top) of the window for use with * shared locking. */ pw->pw_clipdata->pwcd_screen_x = winclip.wc_screenrect.r_left; pw->pw_clipdata->pwcd_screen_y = winclip.wc_screenrect.r_top; /* * Set up clipping utilities */ (void)_pw_setclippers(pw, &winclip.wc_screenrect);}/* * Set up all the various clipping optimizations */_pw_setclippers(pw, screenrectarg) register struct pixwin *pw; struct rect *screenrectarg;{ struct rect bounding; struct rect screenrect; register struct pixwin_clipdata *pwcd = pw->pw_clipdata; screenrect = *screenrectarg; if (pwcd->pwcd_regionrect) { struct rect regionrect; /* * Trim/translate clipping to regionrect */ (void)rl_rectintersection(pwcd->pwcd_regionrect, &pwcd->pwcd_clipping, &pwcd->pwcd_clipping); rl_passtochild(pwcd->pwcd_regionrect->r_left, pwcd->pwcd_regionrect->r_top, &pwcd->pwcd_clipping); (void)rl_normalize(&pwcd->pwcd_clipping); /* * Trim screenrect to regionrect */ regionrect = *pwcd->pwcd_regionrect; rect_passtoparent(screenrect.r_left, screenrect.r_top, ®ionrect); (void)rect_intersection(®ionrect, &screenrect, &screenrect); } bounding = pwcd->pwcd_clipping.rl_bound; if (pwcd->pwcd_state == PWCD_USERDEFINE) { } else { struct rectnode *rn; struct pixwin_prlist *prlnext, *prl; pwcd->pwcd_state = PWCD_MULTIRECTS; pwcd->pwcd_prmulti = pr_region(pw->pw_pixrect, screenrect.r_left, screenrect.r_top, screenrect.r_width, screenrect.r_height); /* * Setup vector clipping stuff. */ for (rn = pwcd->pwcd_clipping.rl_head; rn; rn = rn->rn_next) { prlnext = pwcd->pwcd_prl; prl = (struct pixwin_prlist *) sv_calloc(1, sizeof(struct pixwin_prlist)); prl->prl_pixrect = pr_region(pw->pw_pixrect, screenrect.r_left+rn->rn_rect.r_left, screenrect.r_top+rn->rn_rect.r_top, rn->rn_rect.r_width, rn->rn_rect.r_height); prl->prl_next = prlnext; prl->prl_x = rn->rn_rect.r_left; prl->prl_y = rn->rn_rect.r_top; pwcd->pwcd_prl = prl; } if (pw->pw_prretained) { } else if (!pwcd->pwcd_clipping.rl_head) { pwcd->pwcd_state = PWCD_NULL; pwcd->pwcd_prsingle = pr_region( pw->pw_pixrect, screenrect.r_left, screenrect.r_top, 0, 0); } else if (pwcd->pwcd_clipping.rl_head == pwcd->pwcd_clipping.rl_tail) { pwcd->pwcd_state = PWCD_SINGLERECT; pwcd->pwcd_prsingle = pr_region( pw->pw_pixrect, screenrect.r_left+bounding.r_left, screenrect.r_top+bounding.r_top, bounding.r_width, bounding.r_height); } }}win_getwinclip(windowfd, damaged, winclip, rl) int windowfd; bool damaged; struct winclip *winclip; struct rectlist *rl;{ int err; /* * Copy clipping data from kernel */Again: winclip->wc_blockbytes = rlbufbytes; winclip->wc_block = rlbuf; if (damaged) { err = ioctl(windowfd, WINGETDAMAGEDRL, winclip); } else { err = ioctl(windowfd, WINGETEXPOSEDRL, winclip); } if (err) { extern errno; if (errno == EFBIG) { if (rlbuf) free(rlbuf); rlbufbytes += RLBUFBYTESINC; rlbuf = sv_calloc(1, (unsigned)rlbufbytes); if (rlbufbytes > MAXRLBUFBYTES) (void)werror(err, (damaged)? WINGETDAMAGEDRL: WINGETEXPOSEDRL); goto Again; } (void)werror(err, (damaged)? WINGETDAMAGEDRL: WINGETEXPOSEDRL); } (void)rl_copy((struct rectlist *)(winclip->wc_block), rl); /* * Note this cast should be ok on machines with non-680x0 * alignment due to the way that the kernel lays out the * structures in the byte block. */ (void)rl_sort(rl, rl, RECTS_LEFTTORIGHT); (void)rl_sort(rl, rl, RECTS_TOPTOBOTTOM);}/* * Note: Could change get clipping to alway return the damagedid. * See pw_copy and pw_read for explanation of why damagedid of non 0 is bad * in those situations (fixup is not guarrenteed). */intwin_getdamagedid(windowfd) int windowfd;{ struct winclip winclip; struct rectlist clipping; /* * initialize clipping */ clipping = rl_null; /* * Copy damaged clipping data from kernel */ win_getwinclip(windowfd, 1, &winclip, &clipping); /* * If damage exits then return clipping id */ if (rl_empty(&clipping)) return(0); else { (void)rl_free(&clipping); return(winclip.wc_clipid); }}win_getscreenposition(windowfd, x, y) int windowfd; int *x, *y;{ struct winclip winclip; struct rectlist rl; rl = rl_null; win_getwinclip(windowfd, 0, &winclip, &rl); (void)rl_free(&rl); *x = winclip.wc_screenrect.r_left; *y = winclip.wc_screenrect.r_top;}pwco_reinitclipping(pw) struct pixwin *pw;{ int i; struct pixwin_prlist *prl, *prlnext; /* * Reset clipping data */ (void)rl_free(&pw->pw_clipdata->pwcd_clipping); for (i=0;i<RECTS_SORTS;i++) (void)rl_free(&pw->pw_clipdata->pwcd_clippingsorted[i]); for (prl=pw->pw_clipdata->pwcd_prl;prl;prl = prlnext) { (void)pr_destroy(prl->prl_pixrect); prlnext = prl->prl_next; free((caddr_t)prl); } pw->pw_clipdata->pwcd_prl = (struct pixwin_prlist *) 0; if (pw->pw_clipdata->pwcd_prsingle) { (void)pr_destroy(pw->pw_clipdata->pwcd_prsingle); pw->pw_clipdata->pwcd_prsingle = (struct pixrect *) 0; } if (pw->pw_clipdata->pwcd_prmulti) { (void)pr_destroy(pw->pw_clipdata->pwcd_prmulti); pw->pw_clipdata->pwcd_prmulti = (struct pixrect *) 0; } (void)rl_free(&pw->pw_fixup); pw->pw_clipdata->pwcd_clipid = 0; pw->pw_clipdata->pwcd_state = PWCD_NULL; pw->pw_opshandle = (caddr_t) pw; pw->pw_ops = &pw_opsstd; pw->pw_opsx = pw->pw_clipdata->pwcd_x_offset; pw->pw_opsy = pw->pw_clipdata->pwcd_y_offset; pw->pw_clipdata->pwcd_damagedid = 0; return;}pw_repairretained(pw) struct pixwin *pw;{ struct pixrect *pr = pw->pw_prretained; Rect *r = &pw->pw_clipdata->pwcd_clipping.rl_bound; if (pr == (struct pixrect *)0) return; /* Preload memory pixrect if swapped out by double XOR on left edge */ (void)pr_rop(pr, r->r_left, r->r_top, 1, r->r_height, PIX_NOT(PIX_DST), (Pixrect *)0, 0, 0); (void)pr_rop(pr, r->r_left, r->r_top, 1, r->r_height, PIX_NOT(PIX_DST), (Pixrect *)0, 0, 0); /* Do the repair */ (void)pw_repair(pw, r);}/* Called with r in window coordinate space */pw_repair(pw, r) register Pixwin *pw; register Rect *r;{ extern int pw_dontclipflag; int pw_dontclipflagsaved = pw_dontclipflag; Pw_batch_type typesaved = pw->pw_clipdata->pwcd_batch_type; struct pixrect *prsaved = pw->pw_prretained; Rect r_pw, r_pr; if (prsaved == (struct pixrect *)0 || typesaved != PW_NONE) return; /* Refresh screen from retained pixwin based on rect */ pw->pw_prretained = (struct pixrect *)0; /* Be sure to clip source */ pw_dontclipflag = 0; /* Restore from pixrect */ rect_construct(&r_pw, PW_X_FROM_WIN(pw, r->r_left), PW_Y_FROM_WIN(pw, r->r_top), r->r_width, r->r_height); (void)pw_write(pw, r_pw.r_left, r_pw.r_top, r_pw.r_width, r_pw.r_height, PIX_SRC, prsaved, r_pw.r_left, r_pw.r_top); /* Reset clipping state */ pw_dontclipflag = pw_dontclipflagsaved; pw->pw_prretained = prsaved; pw->pw_clipdata->pwcd_batch_type = typesaved; /* Clear part repaired that didn't have pixrect under it */ rect_construct(&r_pr, 0, 0, prsaved->pr_width, prsaved->pr_height); /* Do quick test to see if anything needs to by cleared */ if (!rect_includesrect(&r_pr, &r_pw)) { Rectlist rl_dif; register struct rectnode *rn; /* Need to determine exactly what to clear */ (void)rl_initwithrect(&r_pw, &rl_dif); (void)rl_rectdifference(&r_pr, &rl_dif, &rl_dif); /* Clear each rect in rl_dif */ for (rn = rl_dif.rl_head; rn; rn = rn->rn_next) { (void)pw_writebackground(pw, rn->rn_rect.r_left, rn->rn_rect.r_top, rn->rn_rect.r_width, rn->rn_rect.r_height, PIX_CLR); } (void)rl_free(&rl_dif); }}intpwo_nop(){ return (0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -