📄 srvfunc.c
字号:
fontp->pfont = GdCreateFont(&scrdev, name, height, NULL); fontp->id = nextfontid++; fontp->owner = curclient; fontp->next = listfontp; listfontp = fontp; return fontp->id;}/* Set the font size for the passed font*/voidGrSetFontSize(GR_FONT_ID fontid, GR_COORD size){ GR_FONT *fontp; fontp = GsFindFont(fontid); if (fontp) GdSetFontSize(fontp->pfont, size);}/* Set the font rotation in tenths of degrees for the passed font*/voidGrSetFontRotation(GR_FONT_ID fontid, int tenthdegrees){ GR_FONT *fontp; fontp = GsFindFont(fontid); if (fontp) GdSetFontRotation(fontp->pfont, tenthdegrees);}/* Set the font size for the passed font*/voidGrSetFontAttr(GR_FONT_ID fontid, int setflags, int clrflags){ GR_FONT *fontp; fontp = GsFindFont(fontid); if (fontp) GdSetFontAttr(fontp->pfont, setflags, clrflags);}/* * Unload and deallocate an existing font. */voidGrDestroyFont(GR_FONT_ID fontid){ GR_FONT *fontp; GR_FONT *prevfontp; fontp = GsFindFont(fontid); if (fontp == NULL) return; if (listfontp == fontp) listfontp = fontp->next; else { prevfontp = listfontp; while (prevfontp->next != fontp) prevfontp = prevfontp->next; prevfontp->next = fontp->next; } GdDestroyFont(fontp->pfont); free(fontp);}/* * Return useful information about the specified font. * Font #0 returns info about the standard font. */voidGrGetFontInfo(GR_FONT_ID font, GR_FONT_INFO *fip){ GR_FONT *fontp; PMWFONT pf; if (font == 0) pf = stdfont; else { fontp = GsFindFont(font); if (!fontp) { memset(fip, 0, sizeof(GR_FONT_INFO)); return; } pf = fontp->pfont; } GdGetFontInfo(pf, fip);}/* * Select events for a window for this client. * The events are a bitmask for the events desired. */void GrSelectEvents(GR_WINDOW_ID wid, GR_EVENT_MASK eventmask){ GR_WINDOW *wp; /* window structure */ GR_EVENT_CLIENT *evp; /* event-client structure */ wp = GsFindWindow(wid); if (wp == NULL) return; /* * See if this client is already in the event client list. * If so, then just replace the events he is selecting for. */ for (evp = wp->eventclients; evp; evp = evp->next) { if (evp->client == curclient) { evp->eventmask = eventmask; return; } } /* * A new client for this window, so allocate a new event client * structure and insert it into the front of the list in the window. */ evp = (GR_EVENT_CLIENT *) malloc(sizeof(GR_EVENT_CLIENT)); if (evp == NULL) { GsError(GR_ERROR_MALLOC_FAILED, wid); return; } evp->client = curclient; evp->eventmask = eventmask; evp->next = wp->eventclients; wp->eventclients = evp; /* * If it's a request for child updates to the root window, * then search entire list and send map events for * mapped windows now. This allows a window manager * to get the mapped window list without another API call. */ if (wid==GR_ROOT_WINDOW_ID && (eventmask & GR_EVENT_MASK_CHLD_UPDATE)) { for (wp = listwp; wp; wp = wp->next) { if (wp->unmapcount == 0) GsDeliverUpdateEvent(wp, GR_UPDATE_MAP, wp->x, wp->y, wp->width, wp->height); } }}static GR_WINDOW *NewWindow(GR_WINDOW *pwp, GR_COORD x, GR_COORD y, GR_SIZE width, GR_SIZE height, GR_SIZE bordersize, GR_COLOR background, GR_COLOR bordercolor){ GR_WINDOW *wp; /* new window*/ if (width <= 0 || height <= 0 || bordersize < 0) { GsError(GR_ERROR_BAD_WINDOW_SIZE, 0); return NULL; } wp = (GR_WINDOW *) malloc(sizeof(GR_WINDOW)); if (wp == NULL) { GsError(GR_ERROR_MALLOC_FAILED, 0); return NULL; } wp->id = nextid++; wp->psd = rootwp->psd; wp->parent = pwp; wp->children = NULL; wp->siblings = pwp->children; wp->next = listwp; wp->x = pwp->x + x; wp->y = pwp->y + y; wp->width = width; wp->height = height; wp->bordersize = bordersize; wp->background = background; wp->bgpixmap = NULL; wp->bgpixmapflags = GR_BACKGROUND_TILE; wp->bordercolor = bordercolor; wp->nopropmask = 0; wp->eventclients = NULL; wp->owner = curclient; wp->cursorid = pwp->cursorid; wp->mapped = GR_FALSE; wp->unmapcount = pwp->unmapcount + 1; wp->output = GR_TRUE; wp->props = 0; wp->title = NULL; pwp->children = wp; listwp = wp; return wp;}/* * Allocate a new window which is a child of the specified window. * The window inherits the cursor of the parent window. * The window is owned by the current client. */GR_WINDOW_IDGrNewWindow(GR_WINDOW_ID parent, GR_COORD x, GR_COORD y, GR_SIZE width, GR_SIZE height, GR_SIZE bordersize, GR_COLOR background, GR_COLOR bordercolor){ GR_WINDOW *pwp; /* parent window */ GR_WINDOW *wp; /* new window */ pwp = GsFindWindow(parent); if (pwp == NULL) return 0; if (!pwp->output) { GsError(GR_ERROR_INPUT_ONLY_WINDOW, pwp->id); return 0; } wp = NewWindow(pwp, x, y, width, height, bordersize, background, bordercolor); return wp? wp->id: 0;}/* * Allocate a new input-only window which is a child of the specified window. * Such a window is invisible, cannot be drawn into, and is only used to * return events. The window inherits the cursor of the parent window. * The window is owned by the current client. */GR_WINDOW_IDGrNewInputWindow(GR_WINDOW_ID parent, GR_COORD x, GR_COORD y, GR_SIZE width, GR_SIZE height){ GR_WINDOW *pwp; /* parent window */ GR_WINDOW *wp; /* new window */ pwp = GsFindWindow(parent); if (pwp == NULL) return 0; wp = NewWindow(pwp, x, y, width, height, 0, BLACK, BLACK); if (wp) { /* convert to input-only window*/ wp->output = GR_FALSE; return wp->id; } return 0;}/* * Allocate a pixmap, can be used with any drawing functions * for offscreen drawing */GR_WINDOW_IDGrNewPixmap(GR_SIZE width, GR_SIZE height, void * pixels){ GR_PIXMAP *pp; PSD psd; int size, linelen, bpp, planes; if (width <= 0 || height <= 0) { /* no error for now, server will desynchronize w/app*/ /*GsError(GR_ERROR_BAD_WINDOW_SIZE, 0);*/ return 0; } /* * allocate offscreen psd. If screen driver doesn't * support blitting, this will fail. Use root window screen * device for compatibility for now. */ planes = rootwp->psd->planes; bpp = rootwp->psd->bpp; psd = rootwp->psd->AllocateMemGC(rootwp->psd); if (!psd) return 0; pp = (GR_PIXMAP *) malloc(sizeof(GR_PIXMAP)); if (pp == NULL) { GsError(GR_ERROR_MALLOC_FAILED, 0); psd->FreeMemGC(psd); return 0; } GdCalcMemGCAlloc(psd, width, height, 0, 0, &size, &linelen); /* Allocate space for pixel values */ if (!pixels) { pixels = calloc(size, 1); psd->flags |= PSF_ADDRMALLOC; } if (!pixels) { free(pp); psd->FreeMemGC(psd); GsError(GR_ERROR_MALLOC_FAILED, 0); return 0; } pp->id = nextid++; pp->next = listpp; pp->psd = psd; pp->x = 0; pp->y = 0; pp->width = width; pp->height = height; pp->owner = curclient; psd->MapMemGC(psd, width, height, planes, bpp, linelen, size, pixels); listpp = pp; return pp->id;}/* * Map the window to make it (and possibly its children) visible on the screen. */voidGrMapWindow(GR_WINDOW_ID wid){ GR_WINDOW *wp; /* window structure */ wp = GsFindWindow(wid); if (!wp || wp->mapped) return; wp->mapped = GR_TRUE; GsWpMapWindow(wp, GR_FALSE);}/* * Unmap the window to make it and its children invisible on the screen. */voidGrUnmapWindow(GR_WINDOW_ID wid){ GR_WINDOW *wp; /* window structure */ wp = GsFindWindow(wid); if (!wp || !wp->mapped) return; GsWpUnmapWindow(wp, GR_FALSE); wp->mapped = GR_FALSE;}/* * Clear the associated area of a window to its background color * or pixmap. Generate expose event for window if exposeflag set. */voidGrClearArea(GR_WINDOW_ID wid, GR_COORD x, GR_COORD y, GR_SIZE width, GR_SIZE height, GR_BOOL exposeflag){ GR_WINDOW *wp; /* window structure */ wp = GsPrepareWindow(wid); if (wp) { if (width == 0) width = wp->width; if (height == 0) height = wp->height; GsWpClearWindow(wp, x, y, width, height, exposeflag); }}/* Return window with keyboard focus.*/GR_WINDOW_IDGrGetFocus(void){ return focuswp->id;}/* * Set the focus to a particular window. * This makes keyboard events only visible to that window or children of it, * depending on the pointer location. */voidGrSetFocus(GR_WINDOW_ID wid){ GR_WINDOW *wp; /* window structure */ wp = GsFindWindow(wid); if (wp == NULL) return; if (wp->unmapcount) { GsError(GR_ERROR_UNMAPPED_FOCUS_WINDOW, wid); return; } /* Check if window wants focus, if not, ignore call*/ if (wp->props & GR_WM_PROPS_NOFOCUS) return; focusfixed = (wp != rootwp); GsWpSetFocus(wp);}/* * Create a new server-based cursor resource. */static int nextcursorid = 1000;GR_CURSOR_IDGrNewCursor(GR_SIZE width, GR_SIZE height, GR_COORD hotx, GR_COORD hoty, GR_COLOR foreground, GR_COLOR background, GR_BITMAP *fgbitmap, GR_BITMAP *bgbitmap){ GR_CURSOR *cp; int bytes; /* * Make sure the size of the bitmap is reasonable. */ if (width <= 0 || width > MWMAX_CURSOR_SIZE || height <= 0 || height > MWMAX_CURSOR_SIZE) { GsError(GR_ERROR_BAD_CURSOR_SIZE, 0); return 0; } cp = (GR_CURSOR *)malloc(sizeof(GR_CURSOR)); if (cp == NULL) { GsError(GR_ERROR_MALLOC_FAILED, 0); return 0; } /* fill in cursor structure*/ cp->cursor.width = width; cp->cursor.height = height; cp->cursor.hotx = hotx; cp->cursor.hoty = hoty; cp->cursor.fgcolor = foreground; cp->cursor.bgcolor = background; bytes = GR_BITMAP_SIZE(width, height) * sizeof(GR_BITMAP); memcpy(&cp->cursor.image, fgbitmap, bytes); memcpy(&cp->cursor.mask, bgbitmap, bytes); cp->id = nextcursorid++; cp->owner = curclient; cp->next = listcursorp; listcursorp = cp; return cp->id;}/* * Destroy a server-based cursor. */voidGrDestroyCursor(GR_CURSOR_ID cid){ GR_CURSOR *cursorp; GR_CURSOR *prevcursorp; cursorp = GsFindCursor(cid); if (cursorp == NULL) return; if (listcursorp == cursorp) listcursorp = cursorp->next; else { prevcursorp = listcursorp; while (prevcursorp->next != cursorp) prevcursorp = prevcursorp->next; prevcursorp->next = cursorp->next; } if (curcursor == cursorp) curcursor = NULL; free(cursorp); GsCheckCursor();}/* * Specify a cursor for a window. * This cursor will only be used within that window, and by default * for its new children. If the cursor is currently within this * window, it will be changed to the new one immediately. * If the new cursor id is 0, revert to the root window cursor. */voidGrSetWindowCursor(GR_WINDOW_ID wid, GR_CURSOR_ID cid){ GR_WINDOW *wp; GR_CURSOR *cp; /* cursor structure */ wp = GsFindWindow(wid); if (wp == NULL) return; if (cid == 0) cp = stdcursor; else { cp = GsFindCursor(cid); if (!cp) return; /* FIXME add server errmsg*/ } wp->cursorid = cid; /* * If this was the current cursor, then draw the new one. */ if (cp == curcursor || curcursor == NULL) { GdMoveCursor(cursorx - cp->cursor.hotx, cursory - cp->cursor.hoty); GdSetCursor(&cp->cursor); } GsCheckCursor();}/* * Move the cursor to the specified absolute screen coordinates. * The coordinates are that of the defined hot spot of the cursor. * The cursor's appearance is changed to that defined for the window * in which the cursor is moved to. In addition, mouse enter, mouse * exit, focus in, and focus out events are generated if necessary. * The current mouse location is also changed. */voidGrMoveCursor(GR_COORD x, GR_COORD y){ /* * Move the cursor only if necessary, offsetting it to * place the hot spot at the specified coordinates. */ if ((x != cursorx) || (y != cursory)) { if(curcursor) { GdMoveCursor(x - curcursor->cursor.hotx, y - curcursor->cursor.hoty); GdMoveMouse(x, y); } cursorx = x; cursory = y; } /* * Now check to see which window the mouse is in, whether or * not the cursor shape should be changed, and whether or not * the input focus window should be changed. */ GsCheckMouseWindow(); GsCheckFocusWindow(); GsCheckCursor();}/* * Set the foreground color in a graphics context. */voidGrSetGCForeground(GR_GC_ID gc, GR_COLOR foreground){ GR_GC *gcp; /* graphics context */ gcp = GsFindGC(gc); if (!gcp || gcp->foreground == foreground) return; gcp->foreground = foreground; gcp->changed = GR_TRUE;}/* * Set the background color in a graphics context. */voidGrSetGCBackground(GR_GC_ID gc, GR_COLOR background){ GR_GC *gcp; /* graphics context */ gcp = GsFindGC(gc); if (!gcp || gcp->background == background) return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -