/*ARGSUSED*/ static void Popdown(Widget shell, XEvent *event, /* unused */ String *params, Cardinal *num_params) { XmScreen screen = (XmScreen) XmGetXmScreen(XtScreen(shell)); XmGrabShellWidget grabshell = (XmGrabShellWidget)shell; Time time; /* Record for replay detection */ if (event && (event->type == ButtonPress || event->type == ButtonRelease)) { grabshell->grab_shell.unpost_time = event->xbutton.time; } if (!(time = XtLastTimestampProcessed(XtDisplay(shell)))) time = CurrentTime; /* CR 9920: Popdown may be called before MapNotify. */ if (grabshell->shell.popped_up && grabshell->grab_shell.mapped) { XErrorHandler old_handler; if (screen -> screen.unpostBehavior == XmUNPOST_AND_REPLAY) GSAllowEvents(shell, ReplayPointer, event ? event->xbutton.time : time); XtUngrabPointer(shell, time); XtUngrabKeyboard(shell, time); _XmPopdown(shell); /* Reset focus to old holder */ old_handler = XSetErrorHandler(IgnoreXErrors); if (time != CurrentTime) time = time - 1; /* Avoid race in wm */ XSetInputFocus(XtDisplay(shell), grabshell->grab_shell.old_focus, grabshell->grab_shell.old_revert_to, time); XSync(XtDisplay(shell), False); XSetErrorHandler(old_handler); } grabshell->grab_shell.mapped = False; }
/****************************************************************************** * * CreateGC: * Called by Initialize and by SetValues. * *****************************************************************************/ static void CreateGC ( Widget w ) { ExmSimpleWidget sw = (ExmSimpleWidget)w; XGCValues values; XtGCMask valueMask; Arg args[2]; Pixmap insensitiveStippleBitmap; /* This function creates two GC's: one to render a sensitive widget and the other to render an insensitive widget. */ /* First, create the sensitive GC (named normal_GC). */ valueMask = GCForeground | GCBackground | GCGraphicsExposures; values.foreground = sw->primitive.foreground; values.background = sw->core.background_pixel; values.graphics_exposures = False; sw->simple.normal_gc = XtGetGC ((Widget)sw, valueMask, &values); /* Next, create the insensitive GC. This GC will share the same foreground, background, and graphics exposures as the sensitive GC, but will hold a different fill style and stipple pattern. The stipple pattern is stored in the XmNinsensitiveStippleBitmap resource of XmScreen. */ valueMask |= GCFillStyle | GCStipple; values.fill_style = FillStippled; /* Gather the Motif-appropriate insensitive stipple bitmap. */ XtSetArg(args[0], XmNinsensitiveStippleBitmap, &insensitiveStippleBitmap); XtGetValues(XmGetXmScreen(XtScreen(w)), args, 1); values.stipple = insensitiveStippleBitmap; sw->simple.insensitive_gc = XtGetGC((Widget)sw, valueMask, &values); }
/* * Almost the same as XmGetPixmap() above, but this time the programmer can * even control the depth of the pixmap she/he wants. */ extern Pixmap XmGetPixmapByDepth(Screen *screen, char *image_name, Pixel foreground, Pixel background, int depth) { LTPixmapDescRec PixmapDesc; LTPixmapDesc PixmapValue; LTImageValue ImageDesc; int image_depth; char *pathname_to_pixmap; unsigned int bitmap_width, bitmap_height; int x_hot, y_hot; XImage *image; Pixmap new_pix, tmp, mask; GC gc; XGCValues values; #ifdef NONSTANDARD_CONVERTERS XpmColorSymbol xpm_colour_symbols[3]; XpmAttributes xpm_attrib; #endif /* NONSTANDARD_CONVERTERS */ values.foreground = foreground; values.background = background; if (PixmapCache == NULL) { LTSetupPixmapCache(); } if (image_name == NULL) { return XmUNSPECIFIED_PIXMAP; } /* * First, we check the pixmap cache to see if such a pixmap is already * there. Therefore we fill in a pixmap description but only use the * first set of fields in the description structure. The second set will * contain information about the pixmap, if a pixmap, as described by the * first set, is already in the cache. */ PixmapDesc.image_name = image_name; PixmapDesc.screen = screen; PixmapDesc.foreground = foreground; PixmapDesc.background = background; PixmapDesc.depth = depth; if (_LTHashTableLookupItem(PixmapCache, (LTHashItemID) & PixmapDesc, (LTHashItemValue *) & PixmapValue)) { /* * There's a pixmap in the cache so we use it and increment its * reference count. */ (PixmapValue->ref_count)++; #if 0 DEBUGOUT(_LtDebug0(__FILE__, NULL, "XmGetPixmapByDepth(scr %p, %s, dpy %p, fg %p, bg %p, d %d) -> %p, refcnt %d\n", screen, image_name, DisplayOfScreen(screen), foreground, background, depth, PixmapValue->pixmap, PixmapValue->ref_count)); #endif return PixmapValue->pixmap; } /* * Okay, we had no luck. Now check the image cache. */ ImageDesc = LTGetImageFromCache(image_name); if (ImageDesc != NULL) { /* * A match from the image cache. Now create the pixmap, add it to * the cache, and return it. */ image = ImageDesc->image; if (image->format == XYBitmap) { image_depth = 1; } else { image_depth = image->depth; } /* create the pixmap */ new_pix = _XmAllocScratchPixmap((XmScreen)XmGetXmScreen(screen), depth, image->width, image->height); tmp = _XmAllocScratchPixmap((XmScreen)XmGetXmScreen(screen), depth, image->width, image->height); gc = XCreateGC(DisplayOfScreen(screen), tmp, 0, NULL); /* move the image information into a temporary pixmap */ XPutImage(DisplayOfScreen(screen), tmp, gc, image, 0, 0, 0, 0, image->width, image->height); XFreeGC(DisplayOfScreen(screen), gc); values.foreground = background; values.background = foreground; gc = XCreateGC(DisplayOfScreen(screen), new_pix, GCForeground | GCBackground, &values); if (image_depth == 1) { XCopyPlane(DisplayOfScreen(screen), tmp, new_pix, gc, 0, 0, image->width, image->height, 0, 0, 1); } else { XCopyArea(DisplayOfScreen(screen), tmp, new_pix, gc, 0, 0, image->width, image->height, 0, 0); } XFreeGC(DisplayOfScreen(screen), gc); /* add the pixmap to the cache */ _LTAddPixmapToCache(image_name, new_pix, screen, foreground, background, depth, image->width, image->height, ImageDesc->hot_x, ImageDesc->hot_y); DEBUGOUT(_LtDebug0(__FILE__, NULL, "XmGetPixmapByDepth(scr %p, %s, dpy %p, fg %p, bg %p, d %d) -> %p new\n", screen, image_name, DisplayOfScreen(screen), foreground, background, depth, new_pix)); return new_pix; } /* since it wasn't in either cache, we search for the file */ /* make sure the search path is there */ if (!_search_path) { _LTCreateSearchPath(); } if (image_name[0] == '/') /* an absolute pathname */ { pathname_to_pixmap = XtNewString(image_name); } else { SubstitutionRec subs[1]; subs[0].match = 'B'; subs[0].substitution = XtNewString(image_name); pathname_to_pixmap = XtResolvePathname(DisplayOfScreen(screen), "bitmaps", NULL, NULL, _search_path, subs, 1, NULL); XtFree(subs[0].substitution); } /* this breaks if X isn't where it's supposed to be. Don't dump core, * just return */ if (pathname_to_pixmap == NULL || strlen(pathname_to_pixmap) == 0) { return XmUNSPECIFIED_PIXMAP; } DEBUGOUT(_LtDebug(__FILE__, NULL, "pathname found is %s\n", pathname_to_pixmap)); /* * For 1.2 converting XPMs to pixmaps is an extension (standard * Motif dosen't read XPMs until version 2) so only do it if * NONSTANDARD_CONVERTERS is defined */ #ifdef NONSTANDARD_CONVERTERS /* Try for an XPM file, then a bitmap */ /* Set up symbolic names for foreground & background colours */ xpm_colour_symbols[0].name = "background"; xpm_colour_symbols[0].value = 0; xpm_colour_symbols[0].pixel = background ; xpm_colour_symbols[1].name = "foreground"; xpm_colour_symbols[1].value = 0; xpm_colour_symbols[1].pixel = foreground ; xpm_colour_symbols[2].name = NULL; xpm_colour_symbols[2].value = "None"; xpm_colour_symbols[2].pixel = background ; xpm_attrib.colorsymbols = xpm_colour_symbols; xpm_attrib.numsymbols = XtNumber(xpm_colour_symbols); xpm_attrib.depth = depth; xpm_attrib.closeness = 40000; xpm_attrib.valuemask = ( XpmSize | XpmReturnPixels | XpmColorSymbols | XpmCloseness | XpmDepth ); if (XpmReadFileToPixmap(DisplayOfScreen(screen), RootWindowOfScreen(screen), pathname_to_pixmap, &new_pix, &mask, &xpm_attrib) == XpmSuccess) { /* add the pixmap to the cache */ _LTAddPixmapToCache(image_name, new_pix, screen, foreground, background, depth, xpm_attrib.width, xpm_attrib.height, xpm_attrib.x_hotspot, xpm_attrib.y_hotspot); } else #endif /* NONSTANDARD_CONVERTERS */ if (XReadBitmapFile(DisplayOfScreen(screen), RootWindowOfScreen(screen), pathname_to_pixmap, &bitmap_width, &bitmap_height, &tmp, &x_hot, &y_hot) == BitmapSuccess) { new_pix = _XmAllocScratchPixmap((XmScreen)XmGetXmScreen(screen), depth, bitmap_width, bitmap_height); gc = XCreateGC(DisplayOfScreen(screen), new_pix, GCForeground | GCBackground, &values); XCopyPlane(DisplayOfScreen(screen), tmp, new_pix, gc, 0, 0, bitmap_width, bitmap_height, 0, 0, 1); XFreeGC(DisplayOfScreen(screen), gc); /* add the pixmap to the cache */ _LTAddPixmapToCache(image_name, new_pix, screen, foreground, background, depth, bitmap_width, bitmap_height, 0, 0 /* FIX ME! hot_x, hot_y! */ ); } else { _XmWarning(NULL, "Couldn't load the pixmap %s.\n", pathname_to_pixmap); new_pix = XmUNSPECIFIED_PIXMAP; } XtFree(pathname_to_pixmap); DEBUGOUT(_LtDebug0(__FILE__, NULL, "XmGetPixmapByDepth(scr %p, %s, dpy %p, fg %p, bg %p, d %d) -> %p new2\n", screen, image_name, DisplayOfScreen(screen), foreground, background, depth, new_pix)); return new_pix; }
/* * IconDraw * * Render given icon in the window of the given widget. */ void IconDraw( Widget widget, IconInfo *iconPtr) { static GC graphicsContext = NULL; static XFontStruct *fontStruct; Display *display = XtDisplayOfObject(widget); Window window = XtWindow(widget); int screen = DefaultScreen(display); XGCValues gcValues; if (graphicsContext == NULL) { gcValues.foreground = BlackPixel(display, screen); gcValues.background = WhitePixel(display, screen); graphicsContext = XCreateGC(display, window, GCForeground | GCBackground, &gcValues); } /* * Draw icon */ gcValues.clip_mask = iconPtr->mask; gcValues.clip_x_origin = iconPtr->icon.x; gcValues.clip_y_origin = iconPtr->icon.y; XChangeGC(display, graphicsContext, GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcValues); XCopyPlane(display, iconPtr->bitmap, window, graphicsContext, 0, 0, iconPtr->icon.width, iconPtr->icon.height, iconPtr->icon.x, iconPtr->icon.y, 1L); /* * Draw icon name centered below icon */ if (iconPtr->name != NULL) { int nameX, nameY; int direction, ascent, decent; XCharStruct overall; Widget xmScreen; if (fontStruct == NULL) { xmScreen = XmGetXmScreen(XtScreen(widget)); XtVaGetValues(xmScreen, XmNfont, &fontStruct, NULL); } XTextExtents(fontStruct, iconPtr->name, strlen(iconPtr->name), &direction, &ascent, &decent, &overall); nameX = (iconPtr->icon.x + (iconPtr->icon.width/2)) - (overall.width/2); nameY = iconPtr->icon.y + iconPtr->icon.height + ICON_TEXT_YGAP + ascent; gcValues.font = fontStruct->fid; gcValues.clip_mask = None; XChangeGC(display, graphicsContext, GCFont | GCClipMask, &gcValues); XDrawString(display, window, graphicsContext, nameX, nameY, iconPtr->name, strlen(iconPtr->name)); } }