📄 misc.c
字号:
if (XrmGetResource(XtDatabase(display), rsrcName, rsrcClass, &type, &value)) { valueString = value.addr; reqID = (int)strtol(valueString, &endPtr, 0); if (endPtr == valueString) { reqID = -1; if (stripCaseCmp(valueString, "Default")) reqID = DefaultVisual(display, screen)->visualid; else if (stripCaseCmp(valueString, "StaticGray")) reqClass = StaticGray; else if (stripCaseCmp(valueString, "StaticColor")) reqClass = StaticColor; else if (stripCaseCmp(valueString, "TrueColor")) reqClass = TrueColor; else if (stripCaseCmp(valueString, "GrayScale")) reqClass = GrayScale; else if (stripCaseCmp(valueString, "PseudoColor")) reqClass = PseudoColor; else if (stripCaseCmp(valueString, "DirectColor")) reqClass = DirectColor; else if (!stripCaseCmp(valueString, "Best")) fprintf(stderr, "Invalid visualID resource value\n"); } } sprintf(rsrcName,"%s.%s", appName, "installColormap"); sprintf(rsrcClass, "%s.%s", appClass, "InstallColormap"); if (XrmGetResource(XtDatabase(display), rsrcName, rsrcClass, &type, &value)) { if (stripCaseCmp(value.addr, "Yes") || stripCaseCmp(value.addr, "True")) installColormap = TRUE; } visTemplate.screen = screen; /* Generate a list of visuals to consider. (Note, vestigial code for user-requested visual depth is left in, just in case that function might be needed again, but it does nothing) */ if (reqID != -1) { visTemplate.visualid = reqID; visList = XGetVisualInfo(display, VisualScreenMask|VisualIDMask, &visTemplate, &nVis); if (visList == NULL) fprintf(stderr, "VisualID resource value not valid\n"); } if (visList == NULL && reqClass != -1 && reqDepth != -1) { visTemplate.class = reqClass; visTemplate.depth = reqDepth; visList = XGetVisualInfo(display, VisualScreenMask| VisualClassMask | VisualDepthMask, &visTemplate, &nVis); if (visList == NULL) fprintf(stderr, "Visual class/depth combination not available\n"); } if (visList == NULL && reqClass != -1) { visTemplate.class = reqClass; visList = XGetVisualInfo(display, VisualScreenMask|VisualClassMask, &visTemplate, &nVis); if (visList == NULL) fprintf(stderr, "Visual Class from resource \"visualID\" not available\n"); } if (visList == NULL && reqDepth != -1) { visTemplate.depth = reqDepth; visList = XGetVisualInfo(display, VisualScreenMask|VisualDepthMask, &visTemplate, &nVis); if (visList == NULL) fprintf(stderr, "Requested visual depth not available\n"); } if (visList == NULL) { visList = XGetVisualInfo(display, VisualScreenMask, &visTemplate, &nVis); if (visList == NULL) { fprintf(stderr, "Internal Error: no visuals available?\n"); *visual = DefaultVisual(display, screen); *depth = DefaultDepth(display, screen); *colormap = DefaultColormap(display, screen); return True; } } /* Choose among the visuals in the candidate list. Prefer maximum depth first then matching default, then largest value of bestClass (I'm not sure whether we actually care about class) */ maxDepth = 0; bestClass = 0; bestVisual = 0; for (i=0; i < nVis; i++) { if (visList[i].depth > maxDepth) { maxDepth = visList[i].depth; bestClass = 0; bestVisual = i; } if (visList[i].depth == maxDepth) { if (visList[i].visual == DefaultVisual(display, screen)) bestVisual = i; if (visList[bestVisual].visual != DefaultVisual(display, screen)) { for (j = 0; j < (int)XtNumber(bestClasses); j++) { if (visList[i].class == bestClasses[j] && j > bestClass) { bestClass = j; bestVisual = i; } } } } } *visual = cachedVisual = visList[bestVisual].visual; *depth = cachedDepth = visList[bestVisual].depth; /* If the chosen visual is not the default, it needs a colormap allocated */ if (*visual == DefaultVisual(display, screen) && !installColormap) *colormap = cachedColormap = DefaultColormap(display, screen); else { *colormap = cachedColormap = XCreateColormap(display, RootWindow(display, screen), cachedVisual, AllocNone); XInstallColormap(display, cachedColormap); } /* printf("Chose visual with depth %d, class %d, colormap %ld, id 0x%x\n", visList[bestVisual].depth, visList[bestVisual].class, *colormap, cachedVisual->visualid); */ /* Fix memory leak */ if (visList != NULL) { XFree(visList); } return (*visual == DefaultVisual(display, screen));}/*** If you want to use a non-default visual with Motif, shells all have to be** created with that visual, depth, and colormap, even if the parent has them** set up properly. Substituting these routines, will append visual args copied** from the parent widget (CreatePopupMenu and CreatePulldownMenu), or from the** best visual, obtained via FindBestVisual above (CreateShellWithBestVis).*/Widget CreateDialogShell(Widget parent, char *name, ArgList arglist, Cardinal argcount){ return addParentVisArgsAndCall(XmCreateDialogShell, parent, name, arglist, argcount);}Widget CreatePopupMenu(Widget parent, char *name, ArgList arglist, Cardinal argcount){ return addParentVisArgsAndCall(XmCreatePopupMenu, parent, name, arglist, argcount);}Widget CreatePulldownMenu(Widget parent, char *name, ArgList arglist, Cardinal argcount){ return addParentVisArgsAndCall(XmCreatePulldownMenu, parent, name, arglist, argcount);}Widget CreatePromptDialog(Widget parent, char *name, ArgList arglist, Cardinal argcount){ return addParentVisArgsAndCall(XmCreatePromptDialog, parent, name, arglist, argcount);}Widget CreateSelectionDialog(Widget parent, char *name, ArgList arglist, Cardinal argcount){ Widget dialog = addParentVisArgsAndCall(XmCreateSelectionDialog, parent, name, arglist, argcount); AddMouseWheelSupport(XmSelectionBoxGetChild(dialog, XmDIALOG_LIST)); return dialog;}Widget CreateFormDialog(Widget parent, char *name, ArgList arglist, Cardinal argcount){ return addParentVisArgsAndCall(XmCreateFormDialog, parent, name, arglist, argcount);}Widget CreateFileSelectionDialog(Widget parent, char *name, ArgList arglist, Cardinal argcount){ Widget dialog = addParentVisArgsAndCall(XmCreateFileSelectionDialog, parent, name, arglist, argcount); AddMouseWheelSupport(XmFileSelectionBoxGetChild(dialog, XmDIALOG_LIST)); AddMouseWheelSupport(XmFileSelectionBoxGetChild(dialog, XmDIALOG_DIR_LIST)); return dialog;}Widget CreateQuestionDialog(Widget parent, char *name, ArgList arglist, Cardinal argcount){ return addParentVisArgsAndCall(XmCreateQuestionDialog, parent, name, arglist, argcount);}Widget CreateMessageDialog(Widget parent, char *name, ArgList arglist, Cardinal argcount){ return addParentVisArgsAndCall(XmCreateMessageDialog, parent, name, arglist, argcount);}Widget CreateErrorDialog(Widget parent, char *name, ArgList arglist, Cardinal argcount){ return addParentVisArgsAndCall(XmCreateErrorDialog, parent, name, arglist, argcount);}Widget CreateShellWithBestVis(String appName, String appClass, WidgetClass class, Display *display, ArgList args, Cardinal nArgs){ Visual *visual; int depth; Colormap colormap; ArgList al; Cardinal ac = nArgs; Widget result; FindBestVisual(display, appName, appClass, &visual, &depth, &colormap); al = (ArgList)XtMalloc(sizeof(Arg) * (nArgs + 3)); if (nArgs != 0) memcpy(al, args, sizeof(Arg) * nArgs); XtSetArg(al[ac], XtNvisual, visual); ac++; XtSetArg(al[ac], XtNdepth, depth); ac++; XtSetArg(al[ac], XtNcolormap, colormap); ac++; result = XtAppCreateShell(appName, appClass, class, display, al, ac); XtFree((char *)al); return result;}Widget CreatePopupShellWithBestVis(String shellName, WidgetClass class, Widget parent, ArgList arglist, Cardinal argcount){ Widget result; ArgList al = addParentVisArgs(parent, arglist, &argcount); result = XtCreatePopupShell(shellName, class, parent, al, argcount); XtFree((char *)al); return result;}/*** Extends an argument list for widget creation with additional arguments** for visual, colormap, and depth. The original argument list is not altered** and it's the caller's responsability to free the returned list.*/static ArgList addParentVisArgs(Widget parent, ArgList arglist, Cardinal *argcount){ Visual *visual; int depth; Colormap colormap; ArgList al; Widget parentShell = parent; /* Find the application/dialog/menu shell at the top of the widget hierarchy, which has the visual resource being used */ while (True) { if (XtIsShell(parentShell)) break; if (parentShell == NULL) { fprintf(stderr, "failed to find shell\n"); exit(EXIT_FAILURE); } parentShell = XtParent(parentShell); } /* Add the visual, depth, and colormap resources to the argument list */ XtVaGetValues(parentShell, XtNvisual, &visual, XtNdepth, &depth, XtNcolormap, &colormap, NULL); al = (ArgList)XtMalloc(sizeof(Arg) * ((*argcount) + 3)); if ((*argcount) != 0) memcpy(al, arglist, sizeof(Arg) * (*argcount)); XtSetArg(al[*argcount], XtNvisual, visual); (*argcount)++; XtSetArg(al[*argcount], XtNdepth, depth); (*argcount)++; XtSetArg(al[*argcount], XtNcolormap, colormap); (*argcount)++; return al;}/*** Calls one of the Motif widget creation routines, splicing in additional** arguments for visual, colormap, and depth.*/static Widget addParentVisArgsAndCall(MotifDialogCreationCall createRoutine, Widget parent, char *name, ArgList arglist, Cardinal argcount){ Widget result; ArgList al = addParentVisArgs(parent, arglist, &argcount); result = (*createRoutine)(parent, name, al, argcount); XtFree((char *)al); return result;}/*** ManageDialogCenteredOnPointer is used in place of XtManageChild for** popping up a dialog to enable the dialog to be centered under the** mouse pointer. Whether it pops up the dialog centered under the pointer** or in its default position centered over the parent widget, depends on** the value set in the SetPointerCenteredDialogs call.** Additionally, this function constrains the size of the dialog to the** screen's size, to avoid insanely wide dialogs with obscured buttons.*/ void ManageDialogCenteredOnPointer(Widget dialogChild){ Widget shell = XtParent(dialogChild); Window root, child; unsigned int mask; unsigned int width, height, borderWidth, depth; int x, y, winX, winY, maxX, maxY, maxWidth, maxHeight; Dimension xtWidth, xtHeight; Boolean mappedWhenManaged; static const int slop = 25; /* Temporarily set value of XmNmappedWhenManaged to stop the dialog from popping up right away */ XtVaGetValues(shell, XmNmappedWhenManaged, &mappedWhenManaged, NULL); XtVaSetValues(shell, XmNmappedWhenManaged, False, NULL); /* Ensure that the dialog doesn't get wider/taller than the screen. We use a hard-coded "slop" size because we don't know the border width until it's on screen, and by then it's too late. Putting this before managing the widgets allows it to get the geometry right on the first pass and also prevents the user from accidentally resizing too wide. */ maxWidth = XtScreen(shell)->width - slop; maxHeight = XtScreen(shell)->height - slop; XtVaSetValues(shell, XmNmaxWidth, maxWidth, XmNmaxHeight, maxHeight, NULL); /* Manage the dialog */ XtManageChild(dialogChild); /* Check to see if the window manager doesn't respect XmNmaxWidth and XmNmaxHeight on the first geometry pass (sawfish, twm, fvwm). For this to work XmNresizePolicy must be XmRESIZE_NONE, otherwise the dialog will try to expand anyway. */ XtVaGetValues(shell, XmNwidth, &xtWidth, XmNheight, &xtHeight, NULL); if (xtWidth > maxWidth) XtVaSetValues(shell, XmNwidth, (Dimension) maxWidth, NULL); if (xtHeight > maxHeight) XtVaSetValues(shell, XmNheight, (Dimension) maxHeight, NULL); /* Only set the x/y position if the centering option is enabled. Avoid getting the coordinates if not so, to save a few round-trips to the server. */ if (PointerCenteredDialogsEnabled) { /* Get the pointer position (x, y) */ XQueryPointer(XtDisplay(shell), XtWindow(shell), &root, &child, &x, &y, &winX, &winY, &mask); /* Translate the pointer position (x, y) into a position for the new window that will place the pointer at its center */ XGetGeometry(XtDisplay(shell), XtWindow(shell), &root, &winX, &winY, &width, &height, &borderWidth, &depth); width += 2 * borderWidth; height += 2 * borderWidth; x -= width/2; y -= height/2; /* Ensure that the dialog remains on screen */ maxX = maxWidth - width; maxY = maxHeight - height; if (x > maxX) x = maxX; if (x < 0) x = 0; if (y > maxY) y = maxY; if (y < 0) y = 0; /* Some window managers (Sawfish) don't appear to respond to the geometry set call in synchronous mode. This causes the window to delay XmNwmTimeout (default 5 seconds) before
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -