📄 srvfunc.c
字号:
GdBlit(dp->psd, dp->x+x, dp->y+y, width, height, srcpsd, srcx, srcy,op);
GdFixCursor(srcpsd); /* FIXME*/
}
/*
* Read the color values from the specified rectangular area of the
* specified drawable into a supplied buffer. If the drawable is a
* window which is obscured by other windows, then the returned values
* will include the values from the covering windows. Regions outside
* of the screen boundaries, or unmapped windows will return black.
*/
void
GrReadArea(GR_DRAW_ID id,GR_COORD x,GR_COORD y,GR_SIZE width,GR_SIZE height,
GR_PIXELVAL *pixels)
{
GR_WINDOW *wp;
GR_PIXMAP *pp = NULL;
if ((wp = GsFindWindow(id)) == NULL && (pp = GsFindPixmap(id)) == NULL){
GsError(GR_ERROR_BAD_WINDOW_ID, id);
return;
}
if (wp != NULL) {
if (wp->unmapcount || (x >= wp->width) || (y >= wp->height) ||
(x + width <= 0) || (y + height <= 0)) {
/* long count;
* GR_PIXELVAL black;
*
* black = GdFindColor(BLACK);
* count = width * height;
* while (count-- > 0)
* *pixels++ = black;
*/
return;
}
GdReadArea(wp->psd, wp->x+x, wp->y+y, width, height, pixels);
}
if (pp != NULL) {
if ((x >= pp->width) || (y >= pp->height) ||
(x + width <= 0) || (y + height <= 0)) {
return;
}
GdReadArea(pp->psd, x, y, width, height, pixels);
}
}
/*
* Draw a point in the specified drawable using the specified
* graphics context.
*/
void
GrPoint(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y)
{
GR_DRAWABLE *dp;
switch (GsPrepareDrawing(id, gc, &dp)) {
case GR_DRAW_TYPE_WINDOW:
case GR_DRAW_TYPE_PIXMAP:
GdPoint(dp->psd, dp->x + x, dp->y + y);
break;
}
}
/*
* Draw points in the specified drawable using the specified
* graphics context.
*/
void
GrPoints(GR_DRAW_ID id, GR_GC_ID gc, GR_COUNT count, GR_POINT *pointtable)
{
GR_DRAWABLE *dp;
GR_POINT *pp;
GR_COUNT i;
PSD psd;
switch (GsPrepareDrawing(id, gc, &dp)) {
case GR_DRAW_TYPE_WINDOW:
case GR_DRAW_TYPE_PIXMAP:
psd = dp->psd;
break;
default:
return;
}
pp = pointtable;
for (i = count; i-- > 0; pp++) {
GdPoint(psd, pp->x + dp->x, pp->y + dp->y);
}
}
/*
* Draw a polygon in the specified drawable using the specified
* graphics context. The polygon is only complete if the first
* point is repeated at the end.
*/
void
GrPoly(GR_DRAW_ID id, GR_GC_ID gc, GR_COUNT count, GR_POINT *pointtable)
{
GR_DRAWABLE *dp;
GR_POINT *pp;
GR_COUNT i;
PSD psd;
switch (GsPrepareDrawing(id, gc, &dp)) {
case GR_DRAW_TYPE_WINDOW:
case GR_DRAW_TYPE_PIXMAP:
psd = dp->psd;
break;
default:
return;
}
/*
* Here for drawing to a window.
* Relocate all the points relative to the window.
*/
pp = pointtable;
for (i = count; i-- > 0; pp++) {
pp->x += dp->x;
pp->y += dp->y;
}
GdPoly(psd, count, pointtable);
#ifdef NONETWORK
/*
* The following is only necessary when the server
* isn't a separate process. We don't want to change the
* user's arguments!
*/
pp = pointtable;
for (i = count; i-- > 0; pp++) {
pp->x -= dp->x;
pp->y -= dp->y;
}
#endif
}
/*
* Draw a filled polygon in the specified drawable using the specified
* graphics context. The last point may be a duplicate of the first
* point, but this is not required.
*/
void
GrFillPoly(GR_DRAW_ID id, GR_GC_ID gc, GR_COUNT count, GR_POINT *pointtable)
{
GR_DRAWABLE *dp;
GR_POINT *pp;
GR_COUNT i;
PSD psd;
switch (GsPrepareDrawing(id, gc, &dp)) {
case GR_DRAW_TYPE_WINDOW:
case GR_DRAW_TYPE_PIXMAP:
psd = dp->psd;
break;
default:
return;
}
/*
* Here for drawing to a window.
* Relocate all the points relative to the window.
*/
pp = pointtable;
for (i = count; i-- > 0; pp++) {
pp->x += dp->x;
pp->y += dp->y;
}
GdFillPoly(psd, count, pointtable);
#ifdef NONETWORK
/*
* The following is only necessary when the server
* isn't a separate process. We don't want to change the
* user's arguments!
*/
pp = pointtable;
for (i = count; i-- > 0; pp++) {
pp->x -= dp->x;
pp->y -= dp->y;
}
#endif
}
/*
* Draw a text string in the specified drawable using the
* specified graphics context.
*/
void
GrText(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y, void *str,
GR_COUNT count, int flags)
{
GR_DRAWABLE *dp;
/* default to baseline alignment if none specified*/
if((flags&(MWTF_TOP|MWTF_BASELINE|MWTF_BOTTOM)) == 0)
flags |= MWTF_BASELINE;
switch (GsPrepareDrawing(id, gc, &dp)) {
case GR_DRAW_TYPE_WINDOW:
case GR_DRAW_TYPE_PIXMAP:
GdText(dp->psd, dp->x + x, dp->y + y, str, count,flags);
break;
}
}
/* Return the system palette entries*/
void
GrGetSystemPalette(GR_PALETTE *pal)
{
/* return 0 count if not in palettized mode*/
memset(pal, 0, sizeof(GR_PALETTE *));
if(rootwp->psd->pixtype == MWPF_PALETTE) {
pal->count = (int)rootwp->psd->ncolors;
GdGetPalette(rootwp->psd, 0, pal->count, pal->palette);
}
}
/* Set the system palette entries from first for count*/
void
GrSetSystemPalette(GR_COUNT first, GR_PALETTE *pal)
{
GdSetPalette(rootwp->psd, first, pal->count, pal->palette);
if (first == 0)
GsRedrawScreen();
}
/* Convert passed color value to pixel value, depending on system mode*/
void
GrFindColor(GR_COLOR c, GR_PIXELVAL *retpixel)
{
*retpixel = GdFindColor(c);
}
/* visible =0, no cursor change; =1, show; else hide*/
void
GrInjectPointerEvent(GR_COORD x, GR_COORD y, int button, int visible)
{
if (visible != 0) {
if (visible == 1)
GdShowCursor(&scrdev);
else
GdHideCursor(&scrdev);
}
GdMoveMouse(x, y);
GsHandleMouseStatus(x, y, button);
}
void
GrInjectKeyboardEvent(GR_WINDOW_ID wid, GR_KEY keyvalue, GR_KEYMOD modifiers,
GR_SCANCODE scancode, GR_BOOL pressed)
{
/* create a keyboard event */
GsDeliverKeyboardEvent(wid,
pressed? GR_EVENT_TYPE_KEY_DOWN: GR_EVENT_TYPE_KEY_UP,
keyvalue, modifiers, scancode);
}
/*
* Set certain window properties, according to flags value
* passed in props.
*/
void
GrSetWMProperties(GR_WINDOW_ID wid, GR_WM_PROPERTIES *props)
{
GR_WINDOW *wp;
int tl = 0; /* Initialized to avoid warning */
/* Find the window structure (generate an error if it doesn't exist) */
wp = GsFindWindow(wid);
if(!wp) {
GsError(GR_ERROR_BAD_WINDOW_ID, wid);
return;
}
/* Set window properties*/
if (props->flags & GR_WM_FLAGS_PROPS)
wp->props = props->props;
/* Set window title*/
if (props->flags & GR_WM_FLAGS_TITLE) {
/* Remove the old title if it exists */
if(wp->title)
free(wp->title);
/* Calculate the space needed to store the new title */
if(props->title)
tl = strlen(props->title) + 1;
/* Check for empty title*/
if(!props->title || tl == 1) {
wp->title = NULL;
} else {
/* Otherwise, allocate some space for the new title */
if(!(wp->title = malloc(tl)))
GsError(GR_ERROR_MALLOC_FAILED, wid);
else
memcpy(wp->title, props->title, tl);
}
}
/* Set window background*/
if (props->flags & GR_WM_FLAGS_BACKGROUND) {
if (wp->background != props->background) {
wp->background = props->background;
GsExposeArea(wp, wp->x, wp->y, wp->width, wp->height,
NULL);
}
}
/* Set window border size*/
if (props->flags & GR_WM_FLAGS_BORDERSIZE) {
if (wp->bordersize != props->bordersize) {
GsWpUnmapWindow(wp, GR_TRUE);
wp->bordersize = props->bordersize;
GsWpMapWindow(wp, GR_TRUE);
}
}
/* Set window border color*/
if (props->flags & GR_WM_FLAGS_BORDERCOLOR) {
if (wp->bordercolor != props->bordercolor) {
wp->bordercolor = props->bordercolor;
if (wp->bordersize)
GsDrawBorder(wp);
}
}
}
/*
* Return all window properties
*/
void
GrGetWMProperties(GR_WINDOW_ID wid, GR_WM_PROPERTIES *props)
{
GR_WINDOW *wp;
/* Find the window structure, no error on invalid window id*/
wp = GsFindWindow(wid);
if(!wp) {
/* set flags to 0 on bad window id*/
memset(props, 0, sizeof(GR_WM_PROPERTIES));
return;
}
/* Return everything, regardless of props->flags*/
props->flags = GR_WM_FLAGS_PROPS | GR_WM_FLAGS_TITLE |
GR_WM_FLAGS_BACKGROUND | GR_WM_FLAGS_BORDERSIZE |
GR_WM_FLAGS_BORDERCOLOR;
props->props = wp->props;
props->title = wp->title;
props->background = wp->background;
props->bordersize = wp->bordersize;
props->bordercolor = wp->bordercolor;
}
void
GrCloseWindow(GR_WINDOW_ID wid)
{
GR_WINDOW *wp;
/* Find the window structure (generate an error if it doesn't exist) */
wp = GsFindWindow(wid);
if(!wp) {
/*
* no error for now, client/server problems
* with nxwm when sent
*/
/*GsError(GR_ERROR_BAD_WINDOW_ID, wid);*/
return;
}
/* Send a CLOSE_REQ event to the client */
GsDeliverGeneralEvent(wp, GR_EVENT_TYPE_CLOSE_REQ, NULL);
}
void
GrKillWindow(GR_WINDOW_ID wid)
{
GR_WINDOW *wp;
/* Find the window structure (generate an error if it doesn't exist) */
wp = GsFindWindow(wid);
if(!wp) {
GsError(GR_ERROR_BAD_WINDOW_ID, wid);
return;
}
/* Forcibly kill the connection to the client */
GsClose(wp->owner->id);
}
/*
* GrGetSystemColor color scheme definitions
*/
/* define color scheme: A (tan), B (winstd) or C (old)*/
#define A
#define A_RGB(r,g,b)
#define B_RGB(r,g,b)
#define C_RGB(r,g,b)
#ifdef A
#undef A_RGB
#define A_RGB(r,g,b) GR_RGB(r,g,b),
#endif
#ifdef B
#undef B_RGB
#define B_RGB(r,g,b) GR_RGB(r,g,b),
#endif
#ifdef C
#undef C_RGB
#define C_RGB(r,g,b) GR_RGB(r,g,b),
#endif
#define MAXSYSCOLORS 20 /* # of GR_COLOR_* system colors*/
static GR_COLOR sysColors[MAXSYSCOLORS] = {
/* desktop background*/
GR_RGB( 0, 128, 128), /* GR_COLOR_DESKTOP */
/* caption colors*/
A_RGB(128, 0, 0) /* GR_COLOR_ACTIVECAPTION */
B_RGB(128, 0, 128) /* GR_COLOR_ACTIVECAPTION */
C_RGB(128, 0, 128) /* GR_COLOR_ACTIVECAPTION */
GR_RGB(255, 255, 255), /* GR_COLOR_ACTIVECAPTIONTEXT */
A_RGB(162, 141, 104) /* GR_COLOR_INACTIVECAPTION */
B_RGB(128, 128, 128) /* GR_COLOR_INACTIVECAPTION */
C_RGB( 0, 64, 128) /* GR_COLOR_INACTIVECAPTION */
GR_RGB(192, 192, 192), /* GR_COLOR_INACTIVECAPTIONTEXT */
/* 3d border shades*/
GR_RGB( 0, 0, 0), /* GR_COLOR_WINDOWFRAME */
A_RGB(162, 141, 104) /* GR_COLOR_BTNSHADOW */
B_RGB(128, 128, 128) /* GR_COLOR_BTNSHADOW */
C_RGB(128, 128, 128) /* GR_COLOR_BTNSHADOW */
A_RGB(213, 204, 187) /* GR_COLOR_3DLIGHT */
B_RGB(223, 223, 223) /* GR_COLOR_3DLIGHT */
C_RGB(192, 192, 192) /* GR_COLOR_3DLIGHT */
A_RGB(234, 230, 221) /* GR_COLOR_BTNHIGHLIGHT */
B_RGB(255, 255, 255) /* GR_COLOR_BTNHIGHLIGHT */
C_RGB(223, 223, 223) /* GR_COLOR_BTNHIGHLIGHT */
/* top level application window backgrounds/text*/
A_RGB(213, 204, 187) /* GR_COLOR_APPWINDOW */
B_RGB(192, 192, 192) /* GR_COLOR_APPWINDOW */
C_RGB(160, 160, 160) /* GR_COLOR_APPWINDOW */
GR_RGB( 0, 0, 0), /* GR_COLOR_APPTEXT */
/* button control backgrounds/text (usually same as app window colors)*/
A_RGB(213, 204, 187) /* GR_COLOR_BTNFACE */
B_RGB(192, 192, 192) /* GR_COLOR_BTNFACE */
C_RGB(160, 160, 160) /* GR_COLOR_BTNFACE */
GR_RGB( 0, 0, 0), /* GR_COLOR_BTNTEXT */
/* edit/listbox control backgrounds/text, selected highlights*/
GR_RGB(255, 255, 255), /* GR_COLOR_WINDOW */
GR_RGB( 0, 0, 0), /* GR_COLOR_WINDOWTEXT */
GR_RGB(128, 0, 0), /* GR_COLOR_HIGHLIGHT */
GR_RGB(255, 255, 255), /* GR_COLOR_HIGHLIGHTTEXT */
GR_RGB( 64, 64, 64), /* GR_COLOR_GRAYTEXT */
/* menu backgrounds/text*/
A_RGB(213, 204, 187) /* GR_COLOR_MENU */
B_RGB(192, 192, 192) /* GR_COLOR_MENU */
C_RGB(160, 160, 160) /* GR_COLOR_MENU */
GR_RGB( 0, 0, 0), /* GR_COLOR_MENUTEXT */
};
/* Return system-defined color*/
GR_COLOR
GrGetSysColor(int index)
{
if(index >= 0 && index < MAXSYSCOLORS)
return sysColors[index];
return 0;
}
void
GrSetScreenSaverTimeout(GR_TIMEOUT timeout)
{
MWTIMER *timer;
screensaver_delay = timeout * 1000;
if((timer = GdFindTimer(GsActivateScreenSaver)))
GdDestroyTimer(timer);
/* 0 timeout cancels timer*/
if (timeout == 0)
return;
GdAddTimer(screensaver_delay, GsActivateScreenSaver,
GsActivateScreenSaver);
}
void
GrSetSelectionOwner(GR_WINDOW_ID wid, GR_CHAR *typelist)
{
GR_WINDOW_ID oldwid = selection_owner.wid;
if(selection_owner.typelist) free(selection_owner.typelist);
selection_owner.wid = wid;
if(wid) {
if(!(selection_owner.typelist = strdup(typelist))) {
GsError(GR_ERROR_MALLOC_FAILED, wid);
selection_owner.wid = 0;
}
} else selection_owner.typelist = NULL;
GsDeliverSelectionChangedEvent(oldwid, wid);
}
GR_WINDOW_ID
GrGetSelectionOwner(GR_CHAR **typelist)
{
*typelist = selection_owner.typelist;
return selection_owner.wid;
}
void
GrRequestClientData(GR_WINDOW_ID wid, GR_WINDOW_ID rid, GR_SERIALNO serial,
GR_MIMETYPE mimetype)
{
GsDeliverClientDataReqEvent(rid, wid, serial, mimetype);
}
void
GrSendClientData(GR_WINDOW_ID wid, GR_WINDOW_ID did, GR_SERIALNO serial,
GR_LENGTH len, GR_LENGTH thislen, void *data)
{
void *p;
if(!(p = malloc(len))) {
GsError(GR_ERROR_MALLOC_FAILED, wid);
return; /* FIXME note no error to application*/
}
memcpy(p, data, thislen);
GsDeliverClientDataEvent(did, wid, serial, len, thislen, p);
}
/*
* Set a window's background pixmap. Note that this doesn't
* cause a screen refres
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -