📄 pw_shared.c
字号:
#ifndef lint#ifdef sccsstatic char sccsid[] = "@(#)pw_shared.c 1.1 92/07/30 Copyr 1987 Sun Micro";#endif#endif/* * Copyright (c) 1987 by Sun Microsystems, Inc. *//* * Pw_shared.c: Use shared memory for faster locking. */#include <sys/types.h>#include <sys/time.h>#include <sys/mman.h>#include <pixrect/pixrect.h>#include <pixrect/pr_planegroups.h>#include <pixrect/memvar.h>#include <sunwindow/rect.h>#include <sunwindow/rectlist.h>#include <sunwindow/cms.h>#include <sunwindow/pixwin.h>#include <sunwindow/win_screen.h>#include <sunwindow/win_cursor.h> #include <sunwindow/win_lock.h>#include <sunwindow/cursor_impl.h> /* for crosshairs active check */static void pw_do_shared_lock(), pw_do_shared_unlock();#define pw_release_lock(which_lock) \ { \ (which_lock)->count = 0; \ (which_lock)->pid = 0; \ (which_lock)->lock = 0; \ }typedef struct pw_dtop_entry { char dtop_name[SCR_NAMESIZE]; int ref_count; Win_lock_block *shared_info;} Pw_dtop_entry;/* set this to TRUE to turn off the shared locking *//* initialize pw_disable_shared_locking to 0. */int pw_disable_shared_locking = 0;static Pw_dtop_entry pw_dtop_table[WIN_LOCK_MAX_DTOP];static int pw_lock_block_bytes;static int pw_mypid;/* return TRUE if lock already taken */#define pw_get_lock(which_lock) \ ((pw_test_set(&(which_lock)->lock)) ? \ TRUE : ((which_lock)->id++, (which_lock)->count = 1, \ (which_lock)->pid = pw_mypid, FALSE))pw_shared_lock(pw, rect_paint) register Pixwin *pw; Rect *rect_paint;{ register Win_lock_block *wl = pw->pw_clipdata->pwcd_wl; /* * Cursors, 24-bit planegroups, and shared locking don't currently * mix too well. */ if (pw->pw_clipdata->pwcd_plane_groups_available[PIXPG_24BIT_COLOR]) return(FALSE); /* * if double buffering is on, we do not want to use the shared * memory lock or else pw_rop and friends will behave abnormally * (for cg{3,5} only) */ if ((pw->pw_clipdata->pwcd_flags & PWCD_DBL_AVAIL) && !pw->pw_clipdata->pwcd_plane_groups_available[PIXPG_24BIT_COLOR] && pw_dbl_rect(pw)) return(FALSE); /* * See if locked already. Assume that don't get here if this * pixwin has the display lock already. * Grabio and window data locks take precedence over display lock. */ if (!wl || pw_get_lock(&wl->mutex)) return FALSE; /* * Don't do own locking if io is grabbed. This is because we * aren't prepared to adequately track the cursor when the * pixwin has multiple plane groups available. We could beef * this up to check to see if multiple available planes are * present before we go to pw_release_lock. * Also, bail out if going to to be taking cursor down * that was put up over another plane group. */ if (wl->waiting || wl->go_to_kernel || win_lock_grabio_locked(wl) || (win_lock_data_locked(wl) && wl->data.pid != pw_mypid) || (win_lock_display_locked(wl) && wl->display.pid != pw_mypid) || (pw->pw_clipdata->pwcd_plane_group != wl->cursor_info.plane_group)){ pw_release_lock(&wl->mutex); return FALSE; } /* See if pixwin clip data out-of-date or xhairs involved */ if ((pw->pw_clipdata->pwcd_clipid != wl->clip_ids[pw->pw_clipdata->pwcd_winnum]) || show_horiz_hair(&wl->cursor_info.cursor) || show_vert_hair(&wl->cursor_info.cursor)) { /* Since have to call kernel to get clipping ... */ pw_release_lock(&wl->mutex); return FALSE; } /* acquire display lock */ if (win_lock_display_locked(wl)) { /* already locked, so bump the count */ wl->display.count++; } else if (pw_get_lock(&wl->display)) { /* locked already (somehow) */ pw_release_lock(&wl->mutex); return FALSE; } pw_do_shared_lock(pw, rect_paint); pw_release_lock(&wl->mutex); return TRUE;}static voidpw_do_shared_lock(pw, rect_paint) register Pixwin *pw; Rect *rect_paint;{ Win_lock_block *wl = pw->pw_clipdata->pwcd_wl; register Win_shared_cursor *shared_cursor = &wl->cursor_info; int original_planes; int planes;#ifdef ecd.cursor short olddata;#endif ecd.cursor /* * See if cursor is active, up on the screen and intersects * area that are going to paint in. If a cursor plane exists - * i.e spare3 is set, you dont have to paint it in */ if (shared_cursor->cursor_active && shared_cursor->cursor_is_up && pw_cursor_intersect_exposed(pw, rect_paint) && (!shared_cursor->spare3)) { /* Take cursor off of the screen */ if (pw->pw_clipdata->pwcd_flags & PWCD_CURSOR_INVERTED) (void)pr_reversevideo(pw->pw_pixrect, 0, 1); win_lock_prepare_screen_pr(shared_cursor); /* Set up full planes */ (void)pr_getattributes(pw->pw_pixrect, &original_planes); planes = PIX_ALL_PLANES;#ifdef planes_fully_implemented pr_putattributes(pw->pw_pixrect, &planes);#else (void)pw_full_putattributes(pw->pw_pixrect, &planes);#endif planes_fully_implemented#ifdef ecd.cusror /* This fix is mainly for MS windows which runs in * reverse video. When we rop from the MS win pixrect * we would use a reverse rop. However, the kernel uses * the shared memory pixrect when it moves the cursor * and doesn't know we rop'd from a reverse video window. * The kernel just uses the display pixrect which has the * attributes that were used when sunview was started. * The fix is to clear the window pixrect MP_REVERSEVIDEO * flag while we rop into the memory pixrect. The kernel * also has some similar code to fix the situation where * sunview was started with -i (inverse). (See sys/ * sunwindowdev/windt.c) */ olddata = ((struct mpr_data *)(pw->pw_pixrect->pr_data))->md_flags; ((struct mpr_data *)(pw->pw_pixrect->pr_data))->md_flags &= ~MP_REVERSEVIDEO;#endif ecd.cursor (void)pr_rop(pw->pw_pixrect, shared_cursor->x, shared_cursor->y, shared_cursor->screen_pr.pr_width, shared_cursor->screen_pr.pr_height, PIX_SRC, &shared_cursor->screen_pr, 0, 0);#ifdef ecd.cursor ((struct mpr_data *)(pw->pw_pixrect->pr_data))->md_flags = olddata;#endif ecd.cursor /* Reset planes */#ifdef planes_fully_implemented pr_putattributes(pw->pw_pixrect, &original_planes);#else (void)pw_full_putattributes(pw->pw_pixrect, &original_planes);#endif planes_fully_implemented if (pw->pw_clipdata->pwcd_flags & PWCD_CURSOR_INVERTED) (void)pr_reversevideo(pw->pw_pixrect, 0, 1); shared_cursor->cursor_is_up = FALSE; }#ifdef DEBUG printf("locked display\n");#endif}pw_shared_unlock(pw) register Pixwin *pw;{ register Win_lock_block *wl = pw->pw_clipdata->pwcd_wl; register Win_shared_cursor *shared_cursor; /* * Cursors, 24-bit planegroups, and shared locking don't currently * mix too well. */ if (pw->pw_clipdata->pwcd_plane_groups_available[PIXPG_24BIT_COLOR]) return(FALSE); /* * if double buffering is on, we do not want to use the shared * memory unlock or else pw_rop and friends will behave abnormally * (for cg{3,5} only) */ if ((pw->pw_clipdata->pwcd_flags & PWCD_DBL_AVAIL) && !pw->pw_clipdata->pwcd_plane_groups_available[PIXPG_24BIT_COLOR] && pw_dbl_rect(pw)) return(FALSE); if (!wl || pw_get_lock(&wl->mutex)) return FALSE; shared_cursor = &wl->cursor_info; /* See if we have it locked, no one waiting for * lock and no xhairs. Also, bail out if going to * to be putting cursor up over another plane group. * * Also, don't do own locking if io is grabbed. This is because we * aren't prepared to adequately track the cursor when the * pixwin has multiple plane groups available. */ if (wl->waiting || wl->go_to_kernel || win_lock_grabio_locked(wl) || wl->status.new_cursor || !win_lock_display_locked(wl) || (wl->display.pid != pw_mypid) || (pw->pw_clipdata->pwcd_plane_group != wl->mouse_plane_group) || show_horiz_hair(&shared_cursor->cursor) || show_vert_hair(&shared_cursor->cursor)) { pw_release_lock(&wl->mutex); return FALSE; } wl->display.count--; if (wl->display.count <= 0) { /* Release the lock */ pw_do_shared_unlock(pw); pw_release_lock(&wl->display); } /* release the mutex lock */ pw_release_lock(&wl->mutex); return TRUE;}static voidpw_do_shared_unlock(pw) register Pixwin *pw;{ register Win_lock_block *wl = pw->pw_clipdata->pwcd_wl; register Win_shared_cursor *shared_cursor = &wl->cursor_info; int original_planes;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -