Пример #1
0
void
TkpGetFontFamilies(
    Tcl_Interp *interp,		/* Interp to hold result. */
    Tk_Window tkwin)		/* For display to query. */
{
    Tcl_Obj *resultPtr;
    XftFontSet *list;
    int i;

    resultPtr = Tcl_NewListObj(0, NULL);

    list = XftListFonts(Tk_Display(tkwin), Tk_ScreenNumber(tkwin),
		(char*)0,		/* pattern elements */
		XFT_FAMILY, (char*)0);	/* fields */
    for (i = 0; i < list->nfont; i++) {
	char *family, **familyPtr = &family;
	if (XftPatternGetString(list->fonts[i], XFT_FAMILY, 0, familyPtr)
		== XftResultMatch)
	{
	    Tcl_Obj *strPtr = Tcl_NewStringObj(family, -1);
	    Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
	}
    }
    XftFontSetDestroy(list);

    Tcl_SetObjResult(interp, resultPtr);
}
Пример #2
0
int XvGrabber::getgrabber()
{
	Tk_Window tk = Tcl::instance().tkmain();
	Display* dpy = Tk_Display(tk);

	int majop, eventbase, errbase;
	if (XQueryExtension(dpy, "XVideo", &majop,
			    &eventbase, &errbase) == False)
		return (-1);

	Window root = DefaultRootWindow(dpy);
	u_int ngrabbers=0;
	XvAdaptorInfo* grabbers;
	if (XvQueryAdaptors(dpy, root, &ngrabbers, &grabbers) != Success)
	  return (-1);
	if (ngrabbers > 1)
	  fprintf(stderr, "XVgrabber: warning: more than one frame grabber\n");
		
        for (int i=2; i<ngrabbers; i++) {
          //if ((grabbers[i].type)&XvOutputMask) {
          if ((grabbers[i].type)&XvInputMask) {
	    fprintf(stderr, "Xv %d grabber: %s\n",i,grabbers[i].name);
	    strncpy(grabber_name, grabbers[i].name, sizeof(grabber_name));
	    grabID_ = grabbers[i].base_id;
          }
        }
        if (!grabID_) return (-1);

	XvFreeAdaptorInfo(grabbers);

	XvQueryEncodings(dpy, grabID_, &nencodings, &encoding);
#if 1
	printf("Encodings(%d): ", nencodings);
	for (int i=0; i<nencodings; i++)
	  printf("%s %d %d\n", encoding[i].name,
		 encoding[i].width, encoding[i].height);
	printf("\n");
#endif

	XAbrightness = XInternAtom(dpy, "XV_BRIGHTNESS", False);
	XAcontrast = XInternAtom(dpy, "XV_CONTRAST", False);
	XAhue = XInternAtom(dpy, "XV_HUE", False);
	XAsaturation = XInternAtom(dpy, "XV_SATURATION", False);
	XAencoding = XInternAtom(dpy, "XV_ENCODING", False);

	XvGetPortAttribute(dpy, grabID_, XAencoding, (int *)&encodingid_);

	if (!XMatchVisualInfo(dpy, Tk_ScreenNumber(tk), 24, TrueColor, &vinfo_))
		return (-1);

	return (0);
}
Пример #3
0
static TkBitmap *
GetBitmap(
    Tcl_Interp *interp,		/* Interpreter to use for error reporting,
				 * this may be NULL. */
    Tk_Window tkwin,		/* Window in which bitmap will be used. */
    const char *string)		/* Description of bitmap. See manual entry for
				 * details on legal syntax. */
{
    Tcl_HashEntry *nameHashPtr, *predefHashPtr;
    TkBitmap *bitmapPtr, *existingBitmapPtr;
    TkPredefBitmap *predefPtr;
    Pixmap bitmap;
    int isNew, width, height, dummy2;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
    ThreadSpecificData *tsdPtr =
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (!dispPtr->bitmapInit) {
	BitmapInit(dispPtr);
    }

    nameHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapNameTable, string,
	    &isNew);
    if (!isNew) {
	existingBitmapPtr = Tcl_GetHashValue(nameHashPtr);
	for (bitmapPtr = existingBitmapPtr; bitmapPtr != NULL;
		bitmapPtr = bitmapPtr->nextPtr) {
	    if ((Tk_Display(tkwin) == bitmapPtr->display) &&
		    (Tk_ScreenNumber(tkwin) == bitmapPtr->screenNum)) {
		bitmapPtr->resourceRefCount++;
		return bitmapPtr;
	    }
	}
    } else {
	existingBitmapPtr = NULL;
    }

    /*
     * No suitable bitmap exists. Create a new bitmap from the information
     * contained in the string. If the string starts with "@" then the rest of
     * the string is a file name containing the bitmap. Otherwise the string
     * must refer to a bitmap defined by a call to Tk_DefineBitmap.
     */

    if (*string == '@') {	/* INTL: ISO char */
	Tcl_DString buffer;
	int result;

	if (Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't specify bitmap with '@' in a safe interpreter",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "BITMAP_FILE", NULL);
	    goto error;
	}

	/*
	 * Note that we need to cast away the const from the string because
	 * Tcl_TranslateFileName is non-const, even though it doesn't modify
	 * the string.
	 */

	string = Tcl_TranslateFileName(interp, (char *) string + 1, &buffer);
	if (string == NULL) {
	    goto error;
	}
	result = TkReadBitmapFile(Tk_Display(tkwin),
		RootWindowOfScreen(Tk_Screen(tkwin)), string,
		(unsigned int *) &width, (unsigned int *) &height,
		&bitmap, &dummy2, &dummy2);
	if (result != BitmapSuccess) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"error reading bitmap file \"%s\"", string));
		Tcl_SetErrorCode(interp, "TK", "BITMAP", "FILE_ERROR", NULL);
	    }
	    Tcl_DStringFree(&buffer);
	    goto error;
	}
	Tcl_DStringFree(&buffer);
    } else {
	predefHashPtr = Tcl_FindHashEntry(&tsdPtr->predefBitmapTable, string);
	if (predefHashPtr == NULL) {
	    /*
	     * The following platform specific call allows the user to define
	     * bitmaps that may only exist during run time. If it returns None
	     * nothing was found and we return the error.
	     */

	    bitmap = TkpGetNativeAppBitmap(Tk_Display(tkwin), string,
		    &width, &height);

	    if (bitmap == None) {
		if (interp != NULL) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bitmap \"%s\" not defined", string));
		    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "BITMAP", string,
			    NULL);
		}
		goto error;
	    }
	} else {
	    predefPtr = Tcl_GetHashValue(predefHashPtr);
	    width = predefPtr->width;
	    height = predefPtr->height;
	    if (predefPtr->native) {
		bitmap = TkpCreateNativeBitmap(Tk_Display(tkwin),
		    predefPtr->source);
		if (bitmap == None) {
		    Tcl_Panic("native bitmap creation failed");
		}
	    } else {
		bitmap = XCreateBitmapFromData(Tk_Display(tkwin),
			RootWindowOfScreen(Tk_Screen(tkwin)),
			predefPtr->source, (unsigned)width, (unsigned)height);
	    }
	}
    }

    /*
     * Add information about this bitmap to our database.
     */

    bitmapPtr = ckalloc(sizeof(TkBitmap));
    bitmapPtr->bitmap = bitmap;
    bitmapPtr->width = width;
    bitmapPtr->height = height;
    bitmapPtr->display = Tk_Display(tkwin);
    bitmapPtr->screenNum = Tk_ScreenNumber(tkwin);
    bitmapPtr->resourceRefCount = 1;
    bitmapPtr->objRefCount = 0;
    bitmapPtr->nameHashPtr = nameHashPtr;
    bitmapPtr->idHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapIdTable,
	    (char *) bitmap, &isNew);
    if (!isNew) {
	Tcl_Panic("bitmap already registered in Tk_GetBitmap");
    }
    bitmapPtr->nextPtr = existingBitmapPtr;
    Tcl_SetHashValue(nameHashPtr, bitmapPtr);
    Tcl_SetHashValue(bitmapPtr->idHashPtr, bitmapPtr);
    return bitmapPtr;

  error:
    if (isNew) {
	Tcl_DeleteHashEntry(nameHashPtr);
    }
    return NULL;
}
Пример #4
0
Pixmap
Tk_AllocBitmapFromObj(
    Tcl_Interp *interp,		/* Interp for error results. This may be
				 * NULL. */
    Tk_Window tkwin,		/* Need the screen the bitmap is used on.*/
    Tcl_Obj *objPtr)		/* Object describing bitmap; see manual entry
				 * for legal syntax of string value. */
{
    TkBitmap *bitmapPtr;

    if (objPtr->typePtr != &tkBitmapObjType) {
	InitBitmapObj(objPtr);
    }
    bitmapPtr = objPtr->internalRep.twoPtrValue.ptr1;

    /*
     * If the object currently points to a TkBitmap, see if it's the one we
     * want. If so, increment its reference count and return.
     */

    if (bitmapPtr != NULL) {
	if (bitmapPtr->resourceRefCount == 0) {
	    /*
	     * This is a stale reference: it refers to a TkBitmap that's no
	     * longer in use. Clear the reference.
	     */

	    FreeBitmapObj(objPtr);
	    bitmapPtr = NULL;
	} else if ((Tk_Display(tkwin) == bitmapPtr->display)
		&& (Tk_ScreenNumber(tkwin) == bitmapPtr->screenNum)) {
	    bitmapPtr->resourceRefCount++;
	    return bitmapPtr->bitmap;
	}
    }

    /*
     * The object didn't point to the TkBitmap that we wanted. Search the list
     * of TkBitmaps with the same name to see if one of the others is the
     * right one.
     */

    if (bitmapPtr != NULL) {
	TkBitmap *firstBitmapPtr = Tcl_GetHashValue(bitmapPtr->nameHashPtr);

	FreeBitmapObj(objPtr);
	for (bitmapPtr = firstBitmapPtr; bitmapPtr != NULL;
		bitmapPtr = bitmapPtr->nextPtr) {
	    if ((Tk_Display(tkwin) == bitmapPtr->display) &&
		    (Tk_ScreenNumber(tkwin) == bitmapPtr->screenNum)) {
		bitmapPtr->resourceRefCount++;
		bitmapPtr->objRefCount++;
		objPtr->internalRep.twoPtrValue.ptr1 = bitmapPtr;
		return bitmapPtr->bitmap;
	    }
	}
    }

    /*
     * Still no luck. Call GetBitmap to allocate a new TkBitmap object.
     */

    bitmapPtr = GetBitmap(interp, tkwin, Tcl_GetString(objPtr));
    objPtr->internalRep.twoPtrValue.ptr1 = bitmapPtr;
    if (bitmapPtr == NULL) {
	return None;
    }
    bitmapPtr->objRefCount++;
    return bitmapPtr->bitmap;
}
Пример #5
0
XilLookup XILWindowAssistor::create_cmap(
    Colormap *cmap, int type, XilIndexList *ilist, 
    XilLookup yuvtorgb, XilLookup colorcube
) {
    unsigned long tmp_colors[256], pixels[256], mask;
    XColor	cdefs[256];
    int		top_colors = 2;	/* colormap indices 255 and 254 */
    int		i, t;
    Xil_unsigned8 *data;
    XilLookup	lut;
    int		cmapsize;
    Display	*display = Tk_Display(window_->tkwin());
    Window	window = Tk_WindowId(window_->tkwin());
    int		screen = Tk_ScreenNumber(window_->tkwin());

    //fprintf(stderr,"XILWindowAssistor::"__FUNCTION__"\n");

    /* Get colormap size */
    switch(type)
    {
    case FT_JPEG:
    case FT_H261:
        cmapsize = xil_lookup_get_num_entries(yuvtorgb);
        break;

    case FT_CELLB:
    default: /* hmm */
        xil_cis_get_attribute(cis_,"DECOMPRESSOR_MAX_CMAP_SIZE", (void**)&cmapsize);
        break;
    } 

    /* Create an X colormap for the cis.*/
    *cmap = XCreateColormap(display, window, DefaultVisual(display,screen), AllocNone);

    /* Allocate X Colormap cells
     *
     * If we do not need the entire colormap, allocate `cmapsize'
     * entries just below the top of the colormap.  Here's how:
     *    Temporarily allocate some entries at the front of the cmap.  
     *    Don't allocate the top_colors (the top two color indices 
     *	  are often used by other applications). 
     *    Allocate the needed entries in the next cmap section
     *    Free the temporary entries.
     * This allows the X-Window manager to use them and reduces the
     * chances of of your window colormap flashing.
     */

    if (cmapsize < 256-top_colors) {
        if (!XAllocColorCells(display, *cmap, 0, &mask, 0,
	        tmp_colors, 256 - cmapsize - top_colors)) {
            fprintf(stderr, " XAllocColorCells for cmap_create failed(1)\n");
        }
    }
  
    if (!XAllocColorCells(display, *cmap, 0, &mask, 0, pixels, cmapsize)) {
        fprintf(stderr, " XAllocColorCells for cmap_create failed(2)\n");
    }
    /* The remaining code assumes that the values returned in pixels[0] through
     * pixels[cmapsize-1] are a contiguous range.
     */

    /* Free the unused colors in the front */
    if (cmapsize < 256-top_colors)
        XFreeColors(display, *cmap, tmp_colors, 256 - cmapsize - top_colors, 0);

#if 0
    if (type == CELLB) {

        /* Initialize the XilIndexList to use when setting the RDWR_INDICES
         * attribute.  In this example, we make all of the indices writable.
         */
        if ( (ilist->pixels = (Xil_unsigned32 *)
                malloc(sizeof(Xil_unsigned32) * cmapsize) ) == NULL ) {
            fprintf(stderr, " out of memory for ilist->pixels create\n");
        }
        ilist->ncolors = cmapsize;

        /* Copy the color cells returned by XAllocColorCells into the ilist */
        for (i = 0; i < cmapsize; i++)
            ilist->pixels[i] = (Xil_unsigned32) pixels[i];
    }
#else 
UNUSED(ilist);
#endif

    /* Allocate memory to hold colormap data. */
    if ( (data = (Xil_unsigned8 *)
            malloc(sizeof(Xil_unsigned8) * cmapsize * 3) ) == NULL ) {
        fprintf(stderr, "xilcis_color: out of memory for cmap data create\n");
    }  

    /* Get the entries for the colormap. The method depends on the compression
     * type.  For CELL, get the entries in the current default colormap.
     * For JPEG, get the entries from the standard lookup table
     * yuv_to_rgb.
     */
    switch(type_) {
#if 0
/*    case FT_CELLB:*/

        /* Get the current values in the colormap */
        for (i = 0; i < cmapsize; i++)
            cdefs[i].pixel = i + pixels[0];

        XQueryColors(display, DefaultColormap(display, screen), cdefs,
                     cmapsize);

        /* Convert the values read from the colormap to an array that can
         * be read by xil_lookup_create.  Note that the colormap values are
         * are stored in the XilLookup in BGR order.
         */
        for (i = 0, j = 0; i < cmapsize; i++, j += 3) {
            data[j] = cdefs[i].blue >> 8;
            data[j + 1] = cdefs[i].green >> 8;
            data[j + 2] = cdefs[i].red >> 8;
        }

        lut = xil_lookup_create(xil_, XIL_BYTE, XIL_BYTE, 3, cmapsize,
				(int)pixels[0], data);
        break;
#endif
    case FT_JPEG:
    case FT_H261:
    case FT_CELLB:
        xil_lookup_get_values(yuvtorgb, xil_lookup_get_offset(yuvtorgb),
                              cmapsize, data);
        xil_lookup_set_offset(colorcube, (unsigned int)pixels[0]);
        for (i = 0, t = 0; i < cmapsize; i++, t += 3) {
            cdefs[i].pixel = pixels[i];
            cdefs[i].flags = DoRed | DoGreen | DoBlue;
            cdefs[i].blue = data[t] << 8;  
            cdefs[i].green = data[t+1] << 8; 
            cdefs[i].red = data[t+2] << 8;  
        }
        XStoreColors(display, *cmap, cdefs, cmapsize);
        lut = yuvtorgb;
        break;
     }

    Tk_SetWindowColormap(window_->tkwin(),*cmap);
    free(data);
    return(lut);
}
Пример #6
0
static UnixFtFont *
InitFont(
    Tk_Window tkwin,
    FcPattern *pattern,
    UnixFtFont *fontPtr)
{
    FcFontSet *set;
    FcCharSet *charset;
    FcResult result;
    XftFont *ftFont;
    int i;

    if (!fontPtr) {
	fontPtr = (UnixFtFont *) ckalloc(sizeof(UnixFtFont));
    }

    FcConfigSubstitute(0, pattern, FcMatchPattern);
    XftDefaultSubstitute(Tk_Display(tkwin), Tk_ScreenNumber(tkwin), pattern);

    /*
     * Generate the list of fonts
     */

    set = FcFontSort(0, pattern, FcTrue, NULL, &result);
    if (!set) {
	FcPatternDestroy(pattern);
	ckfree((char *)fontPtr);
	return NULL;
    }

    fontPtr->fontset = set;
    fontPtr->pattern = pattern;
    fontPtr->faces = (UnixFtFace *) ckalloc(set->nfont * sizeof(UnixFtFace));
    fontPtr->nfaces = set->nfont;

    /*
     * Fill in information about each returned font
     */

    for (i = 0; i < set->nfont; i++) {
	fontPtr->faces[i].ftFont = 0;
	fontPtr->faces[i].source = set->fonts[i];
	if (FcPatternGetCharSet(set->fonts[i], FC_CHARSET, 0,
		&charset) == FcResultMatch) {
	    fontPtr->faces[i].charset = FcCharSetCopy(charset);
	} else {
	    fontPtr->faces[i].charset = 0;
	}
    }

    fontPtr->display = Tk_Display(tkwin);
    fontPtr->screen = Tk_ScreenNumber(tkwin);
    fontPtr->ftDraw = 0;
    fontPtr->color.color.red = 0;
    fontPtr->color.color.green = 0;
    fontPtr->color.color.blue = 0;
    fontPtr->color.color.alpha = 0xffff;
    fontPtr->color.pixel = 0xffffffff;

    /*
     * Fill in platform-specific fields of TkFont.
     */
    ftFont = GetFont(fontPtr, 0);
    fontPtr->font.fid = XLoadFont(Tk_Display(tkwin), "fixed");
    GetTkFontAttributes(ftFont, &fontPtr->font.fa);
    GetTkFontMetrics(ftFont, &fontPtr->font.fm);

    return fontPtr;
}
Пример #7
0
GC
Tk_GetGC(
    Tk_Window tkwin,		/* Window in which GC will be used. */
    register unsigned long valueMask,
				/* 1 bits correspond to values specified in
				 * *valuesPtr; other values are set from
				 * defaults. */
    register XGCValues *valuePtr)
				/* Values are specified here for bits set in
				 * valueMask. */
{
    ValueKey valueKey;
    Tcl_HashEntry *valueHashPtr, *idHashPtr;
    register TkGC *gcPtr;
    int isNew;
    Drawable d, freeDrawable;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (dispPtr->gcInit <= 0) {
	GCInit(dispPtr);
    }

    /*
     * Must zero valueKey at start to clear out pad bytes that may be part of
     * structure on some systems.
     */

    memset(&valueKey, 0, sizeof(valueKey));

    /*
     * First, check to see if there's already a GC that will work for this
     * request (exact matches only, sorry).
     */

    if (valueMask & GCFunction) {
	valueKey.values.function = valuePtr->function;
    } else {
	valueKey.values.function = GXcopy;
    }
    if (valueMask & GCPlaneMask) {
	valueKey.values.plane_mask = valuePtr->plane_mask;
    } else {
	valueKey.values.plane_mask = (unsigned) ~0;
    }
    if (valueMask & GCForeground) {
	valueKey.values.foreground = valuePtr->foreground;
    } else {
	valueKey.values.foreground = 0;
    }
    if (valueMask & GCBackground) {
	valueKey.values.background = valuePtr->background;
    } else {
	valueKey.values.background = 1;
    }
    if (valueMask & GCLineWidth) {
	valueKey.values.line_width = valuePtr->line_width;
    } else {
	valueKey.values.line_width = 0;
    }
    if (valueMask & GCLineStyle) {
	valueKey.values.line_style = valuePtr->line_style;
    } else {
	valueKey.values.line_style = LineSolid;
    }
    if (valueMask & GCCapStyle) {
	valueKey.values.cap_style = valuePtr->cap_style;
    } else {
	valueKey.values.cap_style = CapButt;
    }
    if (valueMask & GCJoinStyle) {
	valueKey.values.join_style = valuePtr->join_style;
    } else {
	valueKey.values.join_style = JoinMiter;
    }
    if (valueMask & GCFillStyle) {
	valueKey.values.fill_style = valuePtr->fill_style;
    } else {
	valueKey.values.fill_style = FillSolid;
    }
    if (valueMask & GCFillRule) {
	valueKey.values.fill_rule = valuePtr->fill_rule;
    } else {
	valueKey.values.fill_rule = EvenOddRule;
    }
    if (valueMask & GCArcMode) {
	valueKey.values.arc_mode = valuePtr->arc_mode;
    } else {
	valueKey.values.arc_mode = ArcPieSlice;
    }
    if (valueMask & GCTile) {
	valueKey.values.tile = valuePtr->tile;
    } else {
	valueKey.values.tile = None;
    }
    if (valueMask & GCStipple) {
	valueKey.values.stipple = valuePtr->stipple;
    } else {
	valueKey.values.stipple = None;
    }
    if (valueMask & GCTileStipXOrigin) {
	valueKey.values.ts_x_origin = valuePtr->ts_x_origin;
    } else {
	valueKey.values.ts_x_origin = 0;
    }
    if (valueMask & GCTileStipYOrigin) {
	valueKey.values.ts_y_origin = valuePtr->ts_y_origin;
    } else {
	valueKey.values.ts_y_origin = 0;
    }
    if (valueMask & GCFont) {
	valueKey.values.font = valuePtr->font;
    } else {
	valueKey.values.font = None;
    }
    if (valueMask & GCSubwindowMode) {
	valueKey.values.subwindow_mode = valuePtr->subwindow_mode;
    } else {
	valueKey.values.subwindow_mode = ClipByChildren;
    }
    if (valueMask & GCGraphicsExposures) {
	valueKey.values.graphics_exposures = valuePtr->graphics_exposures;
    } else {
	valueKey.values.graphics_exposures = True;
    }
    if (valueMask & GCClipXOrigin) {
	valueKey.values.clip_x_origin = valuePtr->clip_x_origin;
    } else {
	valueKey.values.clip_x_origin = 0;
    }
    if (valueMask & GCClipYOrigin) {
	valueKey.values.clip_y_origin = valuePtr->clip_y_origin;
    } else {
	valueKey.values.clip_y_origin = 0;
    }
    if (valueMask & GCClipMask) {
	valueKey.values.clip_mask = valuePtr->clip_mask;
    } else {
	valueKey.values.clip_mask = None;
    }
    if (valueMask & GCDashOffset) {
	valueKey.values.dash_offset = valuePtr->dash_offset;
    } else {
	valueKey.values.dash_offset = 0;
    }
    if (valueMask & GCDashList) {
	valueKey.values.dashes = valuePtr->dashes;
    } else {
	valueKey.values.dashes = 4;
    }
    valueKey.display = Tk_Display(tkwin);
    valueKey.screenNum = Tk_ScreenNumber(tkwin);
    valueKey.depth = Tk_Depth(tkwin);
    valueHashPtr = Tcl_CreateHashEntry(&dispPtr->gcValueTable,
	    (char *) &valueKey, &isNew);
    if (!isNew) {
	gcPtr = Tcl_GetHashValue(valueHashPtr);
	gcPtr->refCount++;
	return gcPtr->gc;
    }

    /*
     * No GC is currently available for this set of values. Allocate a new GC
     * and add a new structure to the database.
     */

    gcPtr = ckalloc(sizeof(TkGC));

    /*
     * Find or make a drawable to use to specify the screen and depth of the
     * GC. We may have to make a small pixmap, to avoid doing
     * Tk_MakeWindowExist on the window.
     */

    freeDrawable = None;
    if (Tk_WindowId(tkwin) != None) {
	d = Tk_WindowId(tkwin);
    } else if (valueKey.depth ==
	    DefaultDepth(valueKey.display, valueKey.screenNum)) {
	d = RootWindow(valueKey.display, valueKey.screenNum);
    } else {
	d = Tk_GetPixmap(valueKey.display,
		RootWindow(valueKey.display, valueKey.screenNum),
		1, 1, valueKey.depth);
	freeDrawable = d;
    }

    gcPtr->gc = XCreateGC(valueKey.display, d, valueMask, &valueKey.values);
    gcPtr->display = valueKey.display;
    gcPtr->refCount = 1;
    gcPtr->valueHashPtr = valueHashPtr;
    idHashPtr = Tcl_CreateHashEntry(&dispPtr->gcIdTable,
	    (char *) gcPtr->gc, &isNew);
    if (!isNew) {
	Tcl_Panic("GC already registered in Tk_GetGC");
    }
    Tcl_SetHashValue(valueHashPtr, gcPtr);
    Tcl_SetHashValue(idHashPtr, gcPtr);
    if (freeDrawable != None) {
	Tk_FreePixmap(valueKey.display, freeDrawable);
    }

    return gcPtr->gc;
}
Пример #8
0
static UnixFtFont *
InitFont(
    Tk_Window tkwin,
    FcPattern *pattern,
    UnixFtFont *fontPtr)
{
    FcFontSet *set;
    FcCharSet *charset;
    FcResult result;
    XftFont *ftFont;
    int i, iWidth;

    if (!fontPtr) {
	fontPtr = ckalloc(sizeof(UnixFtFont));
    }

    FcConfigSubstitute(0, pattern, FcMatchPattern);
    XftDefaultSubstitute(Tk_Display(tkwin), Tk_ScreenNumber(tkwin), pattern);

    /*
     * Generate the list of fonts
     */

    set = FcFontSort(0, pattern, FcTrue, NULL, &result);
    if (!set) {
	ckfree(fontPtr);
	return NULL;
    }

    fontPtr->fontset = set;
    fontPtr->pattern = pattern;
    fontPtr->faces = ckalloc(set->nfont * sizeof(UnixFtFace));
    fontPtr->nfaces = set->nfont;

    /*
     * Fill in information about each returned font
     */

    for (i = 0; i < set->nfont; i++) {
	fontPtr->faces[i].ftFont = 0;
	fontPtr->faces[i].ft0Font = 0;
	fontPtr->faces[i].source = set->fonts[i];
	if (FcPatternGetCharSet(set->fonts[i], FC_CHARSET, 0,
		&charset) == FcResultMatch) {
	    fontPtr->faces[i].charset = FcCharSetCopy(charset);
	} else {
	    fontPtr->faces[i].charset = 0;
	}
	fontPtr->faces[i].angle = 0.0;
    }

    fontPtr->display = Tk_Display(tkwin);
    fontPtr->screen = Tk_ScreenNumber(tkwin);
    fontPtr->ftDraw = 0;
    fontPtr->color.color.red = 0;
    fontPtr->color.color.green = 0;
    fontPtr->color.color.blue = 0;
    fontPtr->color.color.alpha = 0xffff;
    fontPtr->color.pixel = 0xffffffff;

    /*
     * Fill in platform-specific fields of TkFont.
     */

    ftFont = GetFont(fontPtr, 0, 0.0);
    fontPtr->font.fid = XLoadFont(Tk_Display(tkwin), "fixed");
    GetTkFontAttributes(ftFont, &fontPtr->font.fa);
    GetTkFontMetrics(ftFont, &fontPtr->font.fm);

    /*
     * Fontconfig can't report any information about the position or thickness
     * of underlines or overstrikes. Thus, we use some defaults that are
     * hacked around from backup defaults in tkUnixFont.c, which are in turn
     * based on recommendations in the X manual. The comments from that file
     * leading to these computations were:
     *
     *	    If the XA_UNDERLINE_POSITION property does not exist, the X manual
     *	    recommends using half the descent.
     *
     *	    If the XA_UNDERLINE_THICKNESS property does not exist, the X
     *	    manual recommends using the width of the stem on a capital letter.
     *	    I don't know of a way to get the stem width of a letter, so guess
     *	    and use 1/3 the width of a capital I.
     *
     * Note that nothing corresponding to *either* property is reported by
     * Fontconfig at all. [Bug 1961455]
     */

    {
	TkFont *fPtr = &fontPtr->font;

	fPtr->underlinePos = fPtr->fm.descent / 2;
	Tk_MeasureChars((Tk_Font) fPtr, "I", 1, -1, 0, &iWidth);
	fPtr->underlineHeight = iWidth / 3;
	if (fPtr->underlineHeight == 0) {
	    fPtr->underlineHeight = 1;
	}
	if (fPtr->underlineHeight + fPtr->underlinePos > fPtr->fm.descent) {
	    fPtr->underlineHeight = fPtr->fm.descent - fPtr->underlinePos;
	    if (fPtr->underlineHeight == 0) {
		fPtr->underlinePos--;
		fPtr->underlineHeight = 1;
	    }
	}
    }

    return fontPtr;
}
Пример #9
0
SCISHARE int
OpenGLCmd(ClientData clientData, Tcl_Interp *interp,
          int argc, CONST84 char **argv)
{
  Tk_Window mainwin = (Tk_Window) clientData;
  OpenGLClientData *OpenGLPtr;
  Colormap cmap;
  Tk_Window tkwin;
  XVisualInfo temp_vi;
  int tempid;
  int n;

#ifndef _WIN32
  int attributes[50];
  int idx = 0;
#endif


  if (argc < 2) 
  {
    Tcl_AppendResult(interp, "wrong # args:  should be \"",
                     argv[0], " pathName ?options?\"",
                     (char *) NULL);
    return TCL_ERROR;
  }

  tkwin = Tk_CreateWindowFromPath(interp, mainwin, argv[1], (char *) NULL);
  if (tkwin == NULL) 
  {
    return TCL_ERROR;
  }
  Tk_SetClass(tkwin, "OpenGL");

  /* Allocate and initialize the widget record. */
  OpenGLPtr = (OpenGLClientData *) ckalloc(sizeof(OpenGLClientData));
  OpenGLPtr->geometry = 0;
  OpenGLPtr->cursor = 0;

  OpenGLPtr->interp = interp;
  OpenGLPtr->tkwin = tkwin;
  OpenGLPtr->display = Tk_Display(tkwin);
  OpenGLPtr->x11_win=0;
  OpenGLPtr->screen_number = Tk_ScreenNumber(tkwin);

#ifndef _WIN32
  OpenGLPtr->glx_win=0;
  OpenGLPtr->fb_configs=glXGetFBConfigs(OpenGLPtr->display, 
                                        OpenGLPtr->screen_number, 
                                        &(OpenGLPtr->num_fb));
#else
  OpenGLPtr->hDC = 0;
#endif
  OpenGLPtr->vi=0;
  OpenGLPtr->cx=0;
  
  Tk_CreateEventHandler(OpenGLPtr->tkwin, 
                        StructureNotifyMask,
                        OpenGLEventProc, 
                        (ClientData) OpenGLPtr);
  
  Tcl_CreateCommand(interp, 
                    Tk_PathName(OpenGLPtr->tkwin), 
                    OpenGLWidgetCmd,
                    (ClientData) OpenGLPtr, 
                    (Tcl_CmdDeleteProc *)0);
  if (OpenGLConfigure(interp, OpenGLPtr, argc-2, argv+2, 0) != TCL_OK) 
  {
    return TCL_ERROR;
  }

  tempid = OpenGLPtr->visualid;

  if (OpenGLPtr->visualid) 
  {
    temp_vi.visualid = OpenGLPtr->visualid;
    OpenGLPtr->vi = 
      XGetVisualInfo(OpenGLPtr->display, VisualIDMask, &temp_vi, &n);
    if(!OpenGLPtr->vi || n!=1)
    {
      Tcl_AppendResult(interp, "Error finding visual", NULL);
      return TCL_ERROR;
    }

  } 
  else 
  {
    /*
     * Pick the right visual...
     */
#ifndef _WIN32
    attributes[idx++]=GLX_BUFFER_SIZE;
    attributes[idx++]=OpenGLPtr->buffersize;
    attributes[idx++]=GLX_LEVEL;
    attributes[idx++]=OpenGLPtr->level;
    if(OpenGLPtr->rgba)
      attributes[idx++]=GLX_RGBA;
    if(OpenGLPtr->doublebuffer)
      attributes[idx++]=GLX_DOUBLEBUFFER;
    if(OpenGLPtr->stereo)
      attributes[idx++]=GLX_STEREO;
    attributes[idx++]=GLX_AUX_BUFFERS;
    attributes[idx++]=OpenGLPtr->auxbuffers;
    attributes[idx++]=GLX_RED_SIZE;
    attributes[idx++]=OpenGLPtr->redsize;
    attributes[idx++]=GLX_GREEN_SIZE;
    attributes[idx++]=OpenGLPtr->greensize;
    attributes[idx++]=GLX_BLUE_SIZE;
    attributes[idx++]=OpenGLPtr->bluesize;
    attributes[idx++]=GLX_ALPHA_SIZE;
    attributes[idx++]=OpenGLPtr->alphasize;
    attributes[idx++]=GLX_DEPTH_SIZE;
    attributes[idx++]=OpenGLPtr->depthsize;
    attributes[idx++]=GLX_STENCIL_SIZE;
    attributes[idx++]=OpenGLPtr->stencilsize;
    attributes[idx++]=GLX_ACCUM_RED_SIZE;
    attributes[idx++]=OpenGLPtr->accumredsize;
    attributes[idx++]=GLX_ACCUM_GREEN_SIZE;
    attributes[idx++]=OpenGLPtr->accumgreensize;
    attributes[idx++]=GLX_ACCUM_BLUE_SIZE;
    attributes[idx++]=OpenGLPtr->accumbluesize;
    attributes[idx++]=GLX_ACCUM_ALPHA_SIZE;
    attributes[idx++]=OpenGLPtr->accumalphasize;
    attributes[idx++]=None;

    OpenGLPtr->vi = glXChooseVisual(OpenGLPtr->display, 
                                    OpenGLPtr->screen_number,
                                    attributes);
    OpenGLPtr->visualid=tempid;

#else // WIN32

    // I am using the *PixelFormat commands from win32 because according
    // to the Windows page, we should prefer this to wgl*PixelFormatARB.
    // Unfortunately, this means that the Windows code will differ
    // substantially from that of other platforms.  However, it has the
    // advantage that we don't have to use the wglGetProc to get
    // the procedure address, or test to see if the applicable extension
    // is supported.  WM:VI

    HWND hWnd = TkWinGetHWND(Tk_WindowId(OpenGLPtr->tkwin));

    // a little ugly, but we need this to be defined before pfd, and
    // we need to follow C initialization rules
    DWORD dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | 
      (OpenGLPtr->doublebuffer ? PFD_DOUBLEBUFFER : 0) |
      (OpenGLPtr->stereo ? PFD_STEREO : 0);
    int iPixelFormat;
    XVisualInfo xvi;
    int n_ret;
    PIXELFORMATDESCRIPTOR pfd = 
    { 
      sizeof(PIXELFORMATDESCRIPTOR),   // size of this pfd 
      1,                     // version number 
      dwFlags,
      PFD_TYPE_RGBA,         // RGBA type 
      OpenGLPtr->buffersize, // color depth
      OpenGLPtr->redsize, 0, 
      OpenGLPtr->greensize, 0, 
      OpenGLPtr->bluesize, 0,  // color bits  
      OpenGLPtr->alphasize,0,  // alpha buffer 
      OpenGLPtr->accumredsize+
      OpenGLPtr->accumgreensize+
      OpenGLPtr->accumbluesize,// accumulation buffer 
      OpenGLPtr->accumredsize, 
      OpenGLPtr->accumgreensize, 
      OpenGLPtr->accumbluesize, 
      OpenGLPtr->accumalphasize,// accum bits 
      OpenGLPtr->depthsize,  // 32-bit z-buffer 
      OpenGLPtr->stencilsize,// no stencil buffer 
      OpenGLPtr->auxbuffers, // no auxiliary buffer 
      PFD_MAIN_PLANE,        // main layer 
      0,                     // reserved 
      0, 0, 0                // layer masks ignored 
    };

    iPixelFormat = ChoosePixelFormat(OpenGLPtr->hDC, &pfd); 
    SetPixelFormat(OpenGLPtr->hDC, iPixelFormat, &pfd);
    OpenGLPtr->visualid = iPixelFormat;
    OpenGLPtr->hDC = GetDC(hWnd);

    xvi.screen = OpenGLPtr->screen_number;
    n_ret=0;
    OpenGLPtr->vi = XGetVisualInfo(OpenGLPtr->display,
                                   VisualScreenMask, &xvi,
                                   &n_ret);
#endif
    if (!OpenGLPtr->vi) 
    {
      Tcl_AppendResult(interp, "Error selecting visual", (char*)NULL);
      return TCL_ERROR;
    }
  }
    
  cmap = XCreateColormap(OpenGLPtr->display,
                         Tk_WindowId(Tk_MainWindow(OpenGLPtr->interp)),
                         OpenGLPtr->vi->visual, 
                         AllocNone);

  if(Tk_SetWindowVisual(OpenGLPtr->tkwin, 
                        OpenGLPtr->vi->visual, 
                        OpenGLPtr->vi->depth, cmap) != 1) 
  {
    Tcl_AppendResult(interp, "Error setting visual for window", (char*)NULL);
    return TCL_ERROR;
  }
  
  XSync(OpenGLPtr->display, False);

  Tcl_SetResult(interp,Tk_PathName(OpenGLPtr->tkwin),TCL_STATIC);
  return TCL_OK;
}