Beispiel #1
0
static void
FreeCursorBits(CursorBitsPtr bits)
{
    if (--bits->refcnt > 0)
	return;
    free(bits->source);
    free(bits->mask);
#ifdef ARGB_CURSOR
    free(bits->argb);
#endif
    dixFiniPrivates(bits, PRIVATE_CURSOR_BITS);
    if (bits->refcnt == 0)
    {
	GlyphSharePtr *prev, this;

	for (prev = &sharedGlyphs;
	     (this = *prev) && (this->bits != bits);
	     prev = &this->next)
	    ;
	if (this)
	{
	    *prev = this->next;
	    CloseFont(this->font, (Font)0);
	    free(this);
	}
	free(bits);
    }
}
Beispiel #2
0
__autoexit void amiga_exit (void)
{
  int i;

  for (i = 0; i < HISTORY_LINES; i++)
  {
    if (*(History + i))
      FreeVec (*(History + i));
    *(History + i) = 0;
  }

  if (GameReq)
    FreeAslRequest (GameReq);
  if (SaveReq)
    FreeAslRequest (SaveReq);
  if (ScriptReq)
    FreeAslRequest (ScriptReq);
  if (Menus)
    FreeMenus (Menus);
  if (Visual)
    FreeVisualInfo (Visual);
  if (ThisProcess)
    ThisProcess->pr_WindowPtr = OldWindowPtr;
  if (Window)
    CloseWindow (Window);
  if (Screen)
    CloseScreen (Screen);
  if (Font)
    CloseFont (Font);
  if (DefaultPubScreen)
    UnlockPubScreen (0, DefaultPubScreen);
  if (Icon)
    FreeDiskObject (Icon);
}
Beispiel #3
0
STATIC VOID FOGadCleanup(struct LayoutData *ld, struct AslBase_intern *AslBase)
{
    struct FOUserData 		*udata = (struct FOUserData *)ld->ld_UserData;
    struct FontRequester 	*req = (struct FontRequester *)ld->ld_Req;
    struct IntReq 		*intreq = ld->ld_IntReq;
//  struct IntFontReq 		*iforeq = (struct IntFontReq *)intreq;
    
    EnterFunc(bug("FOGadCleanup(ld=%p)\n", ld));

    if (ld->ld_Window && ld->ld_GList)
    {
        RemoveGList(ld->ld_Window, ld->ld_GList, -1);
    }
    
    killscrollergadget(&udata->NameScrollGad, AslBase);
    killscrollergadget(&udata->SizeScrollGad, AslBase);

    FreeObjects(&FOREQ_FIRST_OBJECT(udata), &FOREQ_LAST_OBJECT(udata), AslBase);
    
    FOFreeFonts(ld, AslBase);
    		
    if (udata->PreviewFont) CloseFont(udata->PreviewFont);
    
    if (ld->ld_Window)
    {
	req->fo_LeftEdge = intreq->ir_LeftEdge = ld->ld_Window->LeftEdge;
	req->fo_TopEdge  = intreq->ir_TopEdge  = ld->ld_Window->TopEdge;
	req->fo_Width    = intreq->ir_Width    = ld->ld_Window->Width;
	req->fo_Height   = intreq->ir_Height   = ld->ld_Window->Height;
    }
        
    ReturnVoid("FOGadCleanup");
}
Beispiel #4
0
static int MUIMasterExpunge(LIBBASETYPEPTR lh)
{
    MUIMasterBase = (struct Library *)lh;
    
    CloseFont(((struct MUIMasterBase_intern *)MUIMasterBase)->topaz8font);

    return TRUE;
}
Beispiel #5
0
int lib_graphics_f_CloseFont_2(emumsg_syscall_t *msg)
{
	/* Make real syscall */
	CloseFont(
		(struct TextFont *)msg->arg[0]._aptr
	);

	return HOOK_DONE;
}
	static void close_zoomer()
	{
		DrawBitmap(dx, dy, isaves);
		free(isaves);
		isaves = NULL;
		iv_seteventhandler(prevhandler);
		SetKeyboardRate(700, 500);
		PartialUpdate(dx, dy, dw + 4, dh + 4);
		CloseFont(menu_arrow_font);
	}
Beispiel #7
0
IPTR GTText__OM_DISPOSE(Class *cl, Object *o, Msg msg)
{
    struct TextData *data = INST_DATA(cl, o);
    
    if (data->flags & TEXTF_COPYTEXT) FreeVec((APTR)data->toprint);
    if (data->font) CloseFont(data->font);
    if (data->frame) DisposeObject(data->frame);
    
    return DoSuperMethodA(cl, o, msg);

}
Beispiel #8
0
VOID AROSCycle__OM_DISPOSE(Class *cl, Object *o, Msg msg)
{
    struct CycleData *data = INST_DATA(cl, o);
    
    if (EG(o)->GadgetRender)
        DisposeObject(EG(o)->GadgetRender);
	
    if (data->font) CloseFont(data->font);
    
    DoSuperMethodA(cl,o,msg);
}
Beispiel #9
0
void statusbar_destroy(video_canvas_t *canvas)
{
  int i;
  for (i=0; i<b_num; i++) {
    if (canvas->os->pens[i] != -1) {
      ReleasePen(canvas->os->window->WScreen->ViewPort.ColorMap, canvas->os->pens[i]);
      canvas->os->pens[i] = -1;
    }
  }
  if (canvas->os->font != NULL) {
    CloseFont(canvas->os->font);
    canvas->os->font = NULL;
  }
  canvas->os->has_statusbar = 0;
}
void CloseBlankerWindow( void )
{
	if ( BlankerWnd        ) {
		CloseWindow( BlankerWnd );
		BlankerWnd = NULL;
	}

	if ( BlankerGList      ) {
		FreeGadgets( BlankerGList );
		BlankerGList = NULL;
	}

	if ( BlankerFont ) {
		CloseFont( BlankerFont );
		BlankerFont = NULL;
	}
}
Beispiel #11
0
// Free backdrop info
void backdrop_free(BackdropInfo *info)
{
	if (info)
	{
		// Free icons
		backdrop_free_list(info);

		// Free font
		if (info->font) CloseFont(info->font);

		// Free memory
		FreeMemHandle(info->memory);

		// Free structure
		FreeVec(info);
	}
}
Beispiel #12
0
/**************************
**  Listview::Dispose()  **
**************************/
VOID AROSListview__OM_DISPOSE(Class *cl, Object *o, Msg msg)
{
    struct LVData *data;

    data = INST_DATA(cl, o);

    if (data->lvd_DHArray)
	FreeVec(data->lvd_DHArray);

    if (data->lvd_ColAttrs)
	FreeVec(data->lvd_ColAttrs);

    if (data->lvd_Font)
	CloseFont(data->lvd_Font);

   return;
}
Beispiel #13
0
PBTabPanel::~PBTabPanel()
{
	if (m_pActiveTab)
	{
		free(m_pActiveTab);
		m_pActiveTab = NULL;
	}
	if (m_pInactiveTab)
	{
		free(m_pInactiveTab);
		m_pInactiveTab = NULL;
	}
	if (m_pFont)
	{
		CloseFont(m_pFont);
		m_pFont = NULL;
	}
}
Beispiel #14
0
/**
 * does the diX part of freeing the characteristics in the GC.
 *
 *  \param value  must conform to DeleteType
 */
int
FreeGC(void *value, XID gid)
{
    GCPtr pGC = (GCPtr) value;

    CloseFont(pGC->font, (Font) 0);
    (*pGC->funcs->DestroyClip) (pGC);

    if (!pGC->tileIsPixel)
        (*pGC->pScreen->DestroyPixmap) (pGC->tile.pixmap);
    if (pGC->stipple)
        (*pGC->pScreen->DestroyPixmap) (pGC->stipple);

    (*pGC->funcs->DestroyGC) (pGC);
    if (pGC->dash != DefaultDash)
        free(pGC->dash);
    dixFreeObjectWithPrivates(pGC, PRIVATE_GC);
    return Success;
}
Beispiel #15
0
/**
 * does the diX part of freeing the characteristics in the GC.
 *
 *  \param value  must conform to DeleteType
 */
_X_EXPORT int
FreeGC(pointer value, XID gid)
{
    GCPtr pGC = (GCPtr)value;

    CloseFont(pGC->font, (Font)0);
    (* pGC->funcs->DestroyClip)(pGC);

    if (!pGC->tileIsPixel)
	(* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap);
    if (pGC->stipple)
	(* pGC->pScreen->DestroyPixmap)(pGC->stipple);

    (*pGC->funcs->DestroyGC) (pGC);
    if (pGC->dash != DefaultDash)
	xfree(pGC->dash);
    xfree(pGC);
    return(Success);
}
Beispiel #16
0
// Free font data
void font_free(font_data *data)
{
	if (data)
	{
		// Close stuff
		font_close(data);

		// Free font
		if (data->font) CloseFont(data->font);

		// Free port
		DeleteMsgPort(data->appport);

		// Close locale stuff
		if (data->locale.li_Locale)
		{
			CloseLocale(data->locale.li_Locale);
			CloseCatalog(data->locale.li_Catalog);
		}

		// Free args
		FreeArgs(data->args);

		// Free labels
		FreeVec(data->size_labels);

		// Free data
		FreeVec(data);
	}

	// Close library
#ifdef __amigaos4__
	DropInterface((struct Interface *)IDOpus);
#endif
	CloseLibrary(DOpusBase);
}
Beispiel #17
0
/*
 * Open a requester with a fixed font.
 *
 * Only reqtools.library seems to have the ability to use custom fonts.
 * This crashes, if I don't open requtools.library manually. Is this no auto-open library !?
 *
 * Is there really so much code necessary, just to open a fixed width requester !?
 *
 * This is no WinAPI call.
 */
int MessageBox_fixed(HWND hWnd, TCHAR *lpText, TCHAR *lpCaption, UINT uType/*, UINT size*/) {
  rtReqInfo *req;
  ULONG ret;
  BOOL i_opened_it=false;
  struct TextFont *font;
  struct Window *window;
  struct TextAttr myta = {
      "fixed.font",
      8,
      0,
      NULL
  };

  struct TagItem tags[]={
    {RT_TextAttr, (IPTR) &myta},
    {RT_Window, NULL},
    {RTEZ_ReqTitle , (IPTR) lpCaption},
    {RT_ReqPos, REQPOS_CENTERSCR},
    {RT_WaitPointer, TRUE},
    {RT_LockWindow, TRUE},
    {TAG_DONE}
  };

  DebOut("Caption: %s\n", lpCaption);
  DebOut("Text: %s\n", lpText);

  font=OpenDiskFont(&myta);
  if(!font) {
    DebOut("unable to open fixed.font\n");
    tags[0].ti_Tag=TAG_IGNORE;
  }

  window=(struct Window *)XGET(win, MUIA_Window_Window);
  if(window) {
    DebOut("window: %lx\n", window);
    tags[1].ti_Data=(IPTR) window;
  }
  else {
    DebOut("ERROR: no window !?\n");
    tags[1].ti_Tag=TAG_IGNORE;
  }

  /* do I really have to open it !? */
  if(!ReqToolsBase) {
    i_opened_it=TRUE;
    ReqToolsBase = (struct ReqToolsBase *)OpenLibrary("reqtools.library", 0);
  }

  if(!ReqToolsBase) {
    fprintf(stderr, "ERROR: Unable to open reqtools.library!\n");
    DebOut("ERROR: Unable to open reqtools.library!\n");
    return FALSE;
  }

  ret=rtEZRequestA(lpText, "Ok", NULL, NULL, tags);

  if(i_opened_it) {
    CloseLibrary((struct Library *)ReqToolsBase);
    ReqToolsBase=NULL;
  }

  if(font) {
    CloseFont(font);
  }
  return TRUE;
}
Beispiel #18
0
// Get font
void font_get_font(font_data *data)
{
	// Make window busy
	SetWindowBusy(data->window);

	// Existing font?
	if (data->font)
	{
		// Free font
		CloseFont(data->font);
		data->font=NULL;
	}

	// Has the font name changed?
	if (stricmp(data->font_name,data->last_font_name))
	{
		struct FontContentsHeader *fch;
		BPTR lock;

		// Empty labels
		font_build_labels(data,0);

		// Is the name a full path?
		if (strchr(data->font_name,'/') || strchr(data->font_name,':'))
		{
			// Lock font
			if ((lock=Lock(data->font_name,ACCESS_READ)))
			{
				BPTR parent;

				// Get lock on parent
				parent=ParentDir(lock);

				// Unlock lock on file
				UnLock(lock);
				lock=parent;
			}
		}

		// Lock fonts: directory
		else lock=Lock("fonts:",ACCESS_READ);

		// Got lock?
		if (lock)
		{
			// Get font contents
			if ((fch=NewFontContents(lock,FilePart(data->font_name))))
			{
				// Build labels
				font_build_labels(data,fch);

				// Free contents
				DisposeFontContents(fch);
			}

			// Unlock drawer
			UnLock(lock);
		}
	}

	// Fill out TextAttr
	data->attr.ta_Name=data->font_name;
	data->attr.ta_YSize=data->font_size;
	data->attr.ta_Style=0;
	data->attr.ta_Flags=0;

	// Open font
	data->font=OpenDiskFont(&data->attr);

	// Show font name and size
	SetGadgetValue(data->list,GAD_FONT_FONT,(ULONG)FilePart(data->font_name));
	SetGadgetValue(data->list,GAD_FONT_SIZE,data->font_size);

	// Got font?
	if (data->font)
	{
		short ch,pos,hi;

		// First character
		ch=data->font->tf_LoChar;
		if (ch<33) ch=33;

		// Hi character
		hi=data->font->tf_HiChar;
		if (hi>126 && ch<127) hi=127;

		// Build display text
		for (pos=0;ch<hi;ch++,pos++)
			data->font_text[pos]=ch;
		data->font_text[pos]=0;

		// Got labels?
		if (data->size_labels)
		{
			// Find label corresponding to this size
			for (pos=0;data->size_labels[pos];pos++)
			{
				if (atoi(data->size_labels[pos])==data->font_size)
				{
					// Set cycle gadget
					SetGadgetValue(data->list,GAD_FONT_CYCLE,pos);
					break;
				}
			}
		}
	}

	// Empty labels
	else font_build_labels(data,0);

	// Copy name
	strcpy(data->last_font_name,data->font_name);

	// Clear 'first' flag
	data->first=FALSE;

	// Clear window busy
	ClearWindowBusy(data->window);
}
Beispiel #19
0
STATIC IPTR _OM_SET(Class *cl, Object *o,struct opSet *msg)
{
    IPTR retval = (IPTR)0;

    const struct TagItem *tag, *tstate;
    struct LVData *data;

    EnterFunc(bug("ListView::OM_SET\n"));

    data = INST_DATA(cl, o);
    tstate = msg->ops_AttrList;

    /* Set to 1 to signal visual changes */
    while ((tag = NextTagItem(&tstate)) != NULL)
    {
	switch (tag->ti_Tag)
	{
	    case AROSA_Listview_DisplayHook:
		data->lvd_DisplayHook = (struct Hook *)tag->ti_Data;
		retval = 1UL;
		break;

	    case AROSA_Listview_FrontPen:
		data->lvd_FrontPen = (UBYTE)tag->ti_Data;
		retval = 1UL;
		break;

	    case AROSA_Listview_BackPen:
		data->lvd_BackPen = (UBYTE)tag->ti_Data;
		retval = 1UL;
		break;


	    case AROSA_Listview_Visible:
	    case AROSA_Listview_Total:
	    {
		struct TagItem tags[] =
		{
		    {tag->ti_Tag,	tag->ti_Data},
		    {TAG_END}
		};

		NotifyAttrs(cl, o, msg, tags);
	    } break;

	    case AROSA_Listview_List:
	    {

		ULONG numentries;

		struct TagItem tags[] =
		{
		    {AROSA_Listview_First,	0},
		    {AROSA_Listview_Total,	0},
		    {TAG_END}
		};

		data->lvd_List = (Object *)tag->ti_Data;

		GetAttr(AROSA_List_Entries, data->lvd_List, (IPTR *)&numentries);
		SetAttrs(data->lvd_List,
			AROSA_List_Active, AROSV_List_Active_None,
			TAG_END);

		tags[1].ti_Data = numentries;
		DoMethod(o, OM_SET, (IPTR) tags, (IPTR) msg->ops_GInfo);

		retval = 1UL;
	    } break;


	    case AROSA_Listview_HorSpacing:
		data->lvd_HorSpacing = (UBYTE)tag->ti_Data;
		retval = 1UL;
		break;

	    case AROSA_Listview_VertSpacing:
		data->lvd_VertSpacing = (UBYTE)tag->ti_Data;

		ReCalcEntryHeight(data);
		retval = 1UL;
		break;

	    case AROSA_Listview_Format:
	    {
		struct ColumnAttrs *colattrs = data->lvd_ColAttrs;
		ULONG colattrsz = UB(&colattrs[data->lvd_MaxColumns]) - UB(&colattrs[0]);

		memset(colattrs, 0, colattrsz);
		ParseFormatString((STRPTR)tag->ti_Data, data);
		retval = 1UL;
	    } break;

	    case AROSA_Listview_First:
	    {
		struct TagItem tags[] =
		{
		    {AROSA_Listview_First, tag->ti_Data},
		    {TAG_END}
		};

		LONG old = data->lvd_First;

#if DEBUG
		if (msg->MethodID == OM_SET)
                {
			D(bug("_First OM_SET\n"));
		} else
                {
			D(bug("_First OM_UPDATEd, lvd_NC=%d\n",
				data->lvd_NotifyCount));
                }
#endif

		retval = 1UL;
		data->lvd_First = (LONG)tag->ti_Data;

		if (    ( msg->MethodID == OM_UPDATE )
		     && ( old  != data->lvd_First ))
		{
		    struct RastPort *rp;
		    WORD steps;
		    UWORD visible, abs_steps;
		    struct IBox box;

		    steps = tag->ti_Data - old;
		    abs_steps = steps < 0 ? -steps : steps;

		    GetGadgetIBox(o, msg->ops_GInfo, &box);
		    visible = NumVisible(&box, data->lvd_EntryHeight);

		    if (abs_steps < visible >> 1)
		    {
			if ((rp = ObtainGIRPort(msg->ops_GInfo)) != NULL)
			{
			    LONG dy;
			    /* We make the assumption that the listview
			    ** is alvays 'full'. If it isn't, the
			    ** Scroll gadget won't be scrollable, and
			    ** we won't receive any OM_UPDATEs.
			    */

			    dy = steps * data->lvd_EntryHeight;


			    ScrollRaster(rp, 0, dy,
				box.Left + LV_BORDERWIDTH_X,
				box.Top  + LV_BORDERWIDTH_Y,
				box.Left + box.Width  - 1 - LV_BORDERWIDTH_X,
				box.Top  + LV_BORDERWIDTH_Y + visible * data->lvd_EntryHeight);

			    data->lvd_DamageOffset = ((steps > 0) ?
					visible - abs_steps : 0);

			    data->lvd_NumDamaged = abs_steps;

			    DoMethod(o, GM_RENDER, (IPTR) msg->ops_GInfo, (IPTR) rp, GREDRAW_UPDATE);
			    ReleaseGIRPort(rp);
			    retval = 0UL;



			} /* if (ObtainGIRPort succeed) */

		    } /* if (at most half the visible entries scrolled out) */

		} /* if (msg is of type OM_UPDATE) */


		/* Notify change */
		NotifyAttrs(cl, o, msg, tags);

	    } break;

	    case AROSA_Listview_RenderHook:
		data->lvd_RenderHook = (struct Hook *)data->lvd_RenderHook;
		retval = 1UL;
		break;

	    case AROSA_Listview_MultiSelect:
		SETFLAG(data->lvd_Flags, tag->ti_Data, LVFLG_MULTISELECT);
		break;

	    case GA_TextAttr:
	    {
		struct TextFont *tf;

		tf = OpenFont((struct TextAttr *)tag->ti_Data);
		if (tf)
		{
		    if (data->lvd_Font)
		    {
			CloseFont(data->lvd_Font);
		    }
		    data->lvd_Font = tf;
		}
		ReCalcEntryHeight(data);

	     } break;


	    default:
		break;

	} /* switch (tag->ti_Tag) */

    } /* while (more tags to iterate) */

    ReturnPtr("ListView::OM_SET", IPTR, retval);
}
Beispiel #20
0
int
ChangeGC(ClientPtr client, GC * pGC, BITS32 mask, ChangeGCValPtr pUnion)
{
    BITS32 index2;
    int error = 0;
    PixmapPtr pPixmap;
    BITS32 maskQ;

    assert(pUnion);
    pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;

    maskQ = mask;               /* save these for when we walk the GCque */
    while (mask && !error) {
        index2 = (BITS32) lowbit(mask);
        mask &= ~index2;
        pGC->stateChanges |= index2;
        switch (index2) {
        case GCFunction:
        {
            CARD8 newalu;
            NEXTVAL(CARD8, newalu);

            if (newalu <= GXset)
                pGC->alu = newalu;
            else {
                if (client)
                    client->errorValue = newalu;
                error = BadValue;
            }
            break;
        }
        case GCPlaneMask:
            NEXTVAL(unsigned long, pGC->planemask);

            break;
        case GCForeground:
            NEXTVAL(unsigned long, pGC->fgPixel);

            /*
             * this is for CreateGC
             */
            if (!pGC->tileIsPixel && !pGC->tile.pixmap) {
                pGC->tileIsPixel = TRUE;
                pGC->tile.pixel = pGC->fgPixel;
            }
            break;
        case GCBackground:
            NEXTVAL(unsigned long, pGC->bgPixel);

            break;
        case GCLineWidth:      /* ??? line width is a CARD16 */
            NEXTVAL(CARD16, pGC->lineWidth);

            break;
        case GCLineStyle:
        {
            unsigned int newlinestyle;
            NEXTVAL(unsigned int, newlinestyle);

            if (newlinestyle <= LineDoubleDash)
                pGC->lineStyle = newlinestyle;
            else {
                if (client)
                    client->errorValue = newlinestyle;
                error = BadValue;
            }
            break;
        }
        case GCCapStyle:
        {
            unsigned int newcapstyle;
            NEXTVAL(unsigned int, newcapstyle);

            if (newcapstyle <= CapProjecting)
                pGC->capStyle = newcapstyle;
            else {
                if (client)
                    client->errorValue = newcapstyle;
                error = BadValue;
            }
            break;
        }
        case GCJoinStyle:
        {
            unsigned int newjoinstyle;
            NEXTVAL(unsigned int, newjoinstyle);

            if (newjoinstyle <= JoinBevel)
                pGC->joinStyle = newjoinstyle;
            else {
                if (client)
                    client->errorValue = newjoinstyle;
                error = BadValue;
            }
            break;
        }
        case GCFillStyle:
        {
            unsigned int newfillstyle;
            NEXTVAL(unsigned int, newfillstyle);

            if (newfillstyle <= FillOpaqueStippled)
                pGC->fillStyle = newfillstyle;
            else {
                if (client)
                    client->errorValue = newfillstyle;
                error = BadValue;
            }
            break;
        }
        case GCFillRule:
        {
            unsigned int newfillrule;
            NEXTVAL(unsigned int, newfillrule);

            if (newfillrule <= WindingRule)
                pGC->fillRule = newfillrule;
            else {
                if (client)
                    client->errorValue = newfillrule;
                error = BadValue;
            }
            break;
        }
        case GCTile:
            NEXT_PTR(PixmapPtr, pPixmap);

            if ((pPixmap->drawable.depth != pGC->depth) ||
                (pPixmap->drawable.pScreen != pGC->pScreen)) {
                error = BadMatch;
            }
            else {
                pPixmap->refcnt++;
                if (!pGC->tileIsPixel)
                    (*pGC->pScreen->DestroyPixmap) (pGC->tile.pixmap);
                pGC->tileIsPixel = FALSE;
                pGC->tile.pixmap = pPixmap;
            }
            break;
        case GCStipple:
            NEXT_PTR(PixmapPtr, pPixmap);

            if (pPixmap && ((pPixmap->drawable.depth != 1) ||
                            (pPixmap->drawable.pScreen != pGC->pScreen)))
            {
                error = BadMatch;
            }
            else {
                if (pPixmap)
                    pPixmap->refcnt++;
                if (pGC->stipple)
                    (*pGC->pScreen->DestroyPixmap) (pGC->stipple);
                pGC->stipple = pPixmap;
            }
            break;
        case GCTileStipXOrigin:
            NEXTVAL(INT16, pGC->patOrg.x);

            break;
        case GCTileStipYOrigin:
            NEXTVAL(INT16, pGC->patOrg.y);

            break;
        case GCFont:
        {
            FontPtr pFont;
            NEXT_PTR(FontPtr, pFont);

            pFont->refcnt++;
            if (pGC->font)
                CloseFont(pGC->font, (Font) 0);
            pGC->font = pFont;
            break;
        }
        case GCSubwindowMode:
        {
            unsigned int newclipmode;
            NEXTVAL(unsigned int, newclipmode);

            if (newclipmode <= IncludeInferiors)
                pGC->subWindowMode = newclipmode;
            else {
                if (client)
                    client->errorValue = newclipmode;
                error = BadValue;
            }
            break;
        }
        case GCGraphicsExposures:
        {
            unsigned int newge;
            NEXTVAL(unsigned int, newge);

            if (newge <= xTrue)
                pGC->graphicsExposures = newge;
            else {
                if (client)
                    client->errorValue = newge;
                error = BadValue;
            }
            break;
        }
        case GCClipXOrigin:
            NEXTVAL(INT16, pGC->clipOrg.x);

            break;
        case GCClipYOrigin:
            NEXTVAL(INT16, pGC->clipOrg.y);

            break;
        case GCClipMask:
            NEXT_PTR(PixmapPtr, pPixmap);

            if (pPixmap) {
                if ((pPixmap->drawable.depth != 1) ||
                    (pPixmap->drawable.pScreen != pGC->pScreen)) {
                    error = BadMatch;
                    break;
                }
                pPixmap->refcnt++;
            }
            (*pGC->funcs->ChangeClip) (pGC, pPixmap ? CT_PIXMAP : CT_NONE,
                                       (void *) pPixmap, 0);
            break;
        case GCDashOffset:
            NEXTVAL(INT16, pGC->dashOffset);

            break;
        case GCDashList:
        {
            CARD8 newdash;
            NEXTVAL(CARD8, newdash);

            if (newdash == 4) {
                if (pGC->dash != DefaultDash) {
                    free(pGC->dash);
                    pGC->numInDashList = 2;
                    pGC->dash = DefaultDash;
                }
            }
            else if (newdash != 0) {
                unsigned char *dash;

                dash = malloc(2 * sizeof(unsigned char));
                if (dash) {
                    if (pGC->dash != DefaultDash)
                        free(pGC->dash);
                    pGC->numInDashList = 2;
                    pGC->dash = dash;
                    dash[0] = newdash;
                    dash[1] = newdash;
                }
                else
                    error = BadAlloc;
            }
            else {
                if (client)
                    client->errorValue = newdash;
                error = BadValue;
            }
            break;
        }
        case GCArcMode:
        {
            unsigned int newarcmode;
            NEXTVAL(unsigned int, newarcmode);

            if (newarcmode <= ArcPieSlice)
                pGC->arcMode = newarcmode;
            else {
                if (client)
                    client->errorValue = newarcmode;
                error = BadValue;
            }
            break;
        }
        default:
            if (client)
                client->errorValue = maskQ;
            error = BadValue;
            break;
        }
    }                           /* end while mask && !error */

    if (pGC->fillStyle == FillTiled && pGC->tileIsPixel) {
        if (!CreateDefaultTile(pGC)) {
            pGC->fillStyle = FillSolid;
            error = BadAlloc;
        }
    }
    (*pGC->funcs->ChangeGC) (pGC, maskQ);
    return error;
}
Beispiel #21
0
main()
{
  unsigned char str[256], *pp;
  int i;
  struct TextAttr ta = { "topaz.font", 8, FS_NORMAL, FPF_ROMFONT };
  struct RastPort rp;
  struct BitMap bm = { 256, 	/* bytes per row */
		         8,	/* rows */
			 0,	/* flags */
			 1,	/* depth */
			 0,	/* pad */
			 0 };	/* planes */
  struct TextFont *tf;

  InitRastPort (& rp);
  rp.BitMap = &bm;
  bm.Planes[0] = pp = AllocRaster (256 * 8, 8);

  if (!pp)
    {
      fprintf (stderr, "Can't allocate raster!\n");
      exit (1);
    }
  bzero (pp, 256 * 8);
  
  tf = OpenFont (& ta);
  if (! tf)
    {
      fprintf (stderr, "can't open topaz font.\n");
      exit (1);
    }

  SetFont (&rp, tf);

  /* initialize string to be printed */
  for (i = 32; i < 256; i++) str[i - 32] = i;

  Move (&rp, 0, 6);
  
  Text (&rp, str, 256 - 32);
  {
    int bin = open ("bitmap", 1);
    if (bin >= 0)
      {
        write (bin, pp, 256*8);
        close (bin);
      }
  }
  
  /* dump them.. */
  printf ("/* generated automatically by dumpfont.c. *DONT* distribute\n");
  printf ("   this file, it contains information Copyright by Commodore!\n");
  printf ("\n");
  printf ("   This is the (new) topaz80 system font: */\n\n");
  
  printf ("unsigned char kernel_font_width  = 8;\n");
  printf ("unsigned char kernel_font_height = 8;\n");
  printf ("unsigned char kernel_font_lo = 32;\n");
  printf ("unsigned char kernel_font_hi = 255;\n\n");
  
  printf ("unsigned char kernel_cursor[] = {\n");
  printf ("  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };\n\n");
  printf ("unsigned char kernel_font[] = {\n");
  
  for (i = 0; i < 256 - 32; i++)
    {
      printf ("/* %c */ ", i + 32);
      printf ("0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n",
      	      pp[i+0*256], pp[i+1*256], pp[i+2*256], pp[i+3*256],
      	      pp[i+4*256], pp[i+5*256], pp[i+6*256], pp[i+7*256]);
    }
  printf ("};\n");
  
  CloseFont (tf);
  FreeRaster (pp, 256 * 8, 8);
}
void balda_keyboard_view_free(balda_keyboard_view_t* kb)
{
	assert(kb);
	CloseFont(kb->font);
	free(kb);
}
Beispiel #23
0
// Cleanup a lister
void lister_cleanup(Lister *lister,BOOL bye)
{
	struct Node *node;

	// Send goodbye message?
	if (bye)
	{
		// Update our position
		if (!(environment->env->lister_options&LISTEROPTF_SNAPSHOT))
			PositionUpdate(lister,0);

		// Send goodbye message
		IPC_Goodbye(lister->ipc,&main_ipc,WINDOW_LISTER);
	}

	// Is lister iconified?
	if (lister->appicon)
	{
		// Remove AppIcon
		RemoveAppIcon(lister->appicon);

		// Free icon
		FreeDiskObjectCopy(lister->appicon_icon);
	}

	// If we still have a progress window, close it
	lister_progress_off(lister);

	// Showing a special buffer?
	if (lister->cur_buffer==lister->special_buffer)
	{
		// Return to normal
		lister->cur_buffer=lister->old_buffer;
	}

	// Remove buffer lock
	if (lister->cur_buffer)
	{
		// Get buffer list lock
		lock_listlock(&GUI->buffer_list,TRUE);

		// Unlock buffer
		buffer_clear_lock(lister->cur_buffer,1);

		// If buffer is empty or buffer count exceeds maximum, free it
		if (lister->cur_buffer->buf_TotalEntries[0]==0 ||
			GUI->buffer_count>environment->env->settings.max_buffer_count ||
			(environment->env->settings.dir_flags&DIRFLAGS_DISABLE_CACHING))
		{
			// Free buffer
			lister_free_buffer(lister->cur_buffer);
		}

		// Unlock buffer list
		unlock_listlock(&GUI->buffer_list);
	}

	// Free user data
	while ((node=lister->user_data_list.list.lh_Head)->ln_Succ)
	{
		Remove(node);
		FreeMemH(node);
	}

	// Free ports
	if (lister->app_port)
	{
		DOpusAppMessage *msg;
		while ((msg=(DOpusAppMessage *)GetMsg(lister->app_port)))
			ReplyAppMessage(msg);
		DeleteMsgPort(lister->app_port);
	}

	// Close font
	if (lister->font)
		CloseFont(lister->font);	

	// Free signals
	if (lister->abort_signal!=-1)
		FreeSignal(lister->abort_signal);
	if (lister->hot_name_bit!=-1)
		FreeSignal(lister->hot_name_bit);

	// Free timer stuff
	if (lister->timer_port)
	{
		// Close timers
		FreeTimer(lister->foo_timer);
		FreeTimer(lister->icon_drag_timer);
		FreeTimer(lister->busy_timer);
		FreeTimer(lister->edit_timer);
		FreeTimer(lister->scroll_timer);

		// Delete timer port
		DeleteMsgPort(lister->timer_port);
	}

	// Free regions
	if (lister->title_region) DisposeRegion(lister->title_region);
	if (lister->refresh_extra) DisposeRegion(lister->refresh_extra);

	// Free special buffer
	if (lister->special_buffer) buffer_free(lister->special_buffer);

	// Free reselection
	FreeReselect(&lister->reselect);

	// Free history
	Att_RemList(lister->path_history,0);

	// Free popup menu
	PopUpFreeHandle(lister->lister_tool_menu);

	// Free toolbar
	FreeToolBar(lister->toolbar_alloc);

	// Free IPC data
	IPC_Free(lister->ipc);

	// Free lister data
	lister_free(lister);

	// Decrement count
	--main_lister_count;
}
Beispiel #24
0
_X_EXPORT int
dixChangeGC(ClientPtr client, register GC *pGC, register BITS32 mask, CARD32 *pC32, ChangeGCValPtr pUnion)
{
    register BITS32 	index2;
    register int 	error = 0;
    PixmapPtr 		pPixmap;
    BITS32		maskQ;

    assert( (pC32 && !pUnion) || (!pC32 && pUnion) );
    pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;

    maskQ = mask;	/* save these for when we walk the GCque */
    while (mask && !error) 
    {
	index2 = (BITS32) lowbit (mask);
	mask &= ~index2;
	pGC->stateChanges |= index2;
	switch (index2)
	{
	    case GCFunction:
	    {
		CARD8 newalu;
		NEXTVAL(CARD8, newalu);
		if (newalu <= GXset)
		    pGC->alu = newalu;
		else
		{
		    clientErrorValue = newalu;
		    error = BadValue;
		}
		break;
	    }
	    case GCPlaneMask:
		NEXTVAL(unsigned long, pGC->planemask);
		break;
	    case GCForeground:
		NEXTVAL(unsigned long, pGC->fgPixel);
		/*
		 * this is for CreateGC
		 */
		if (!pGC->tileIsPixel && !pGC->tile.pixmap)
		{
		    pGC->tileIsPixel = TRUE;
		    pGC->tile.pixel = pGC->fgPixel;
		}
		break;
	    case GCBackground:
		NEXTVAL(unsigned long, pGC->bgPixel);
		break;
	    case GCLineWidth:		/* ??? line width is a CARD16 */
		 NEXTVAL(CARD16, pGC->lineWidth);
		break;
	    case GCLineStyle:
	    {
		unsigned int newlinestyle;
		NEXTVAL(unsigned int, newlinestyle);
		if (newlinestyle <= LineDoubleDash)
		    pGC->lineStyle = newlinestyle;
		else
		{
		    clientErrorValue = newlinestyle;
		    error = BadValue;
		}
		break;
	    }
	    case GCCapStyle:
	    {
		unsigned int newcapstyle;
		NEXTVAL(unsigned int, newcapstyle);
		if (newcapstyle <= CapProjecting)
		    pGC->capStyle = newcapstyle;
		else
		{
		    clientErrorValue = newcapstyle;
		    error = BadValue;
		}
		break;
	    }
	    case GCJoinStyle:
	    {
		unsigned int newjoinstyle;
		NEXTVAL(unsigned int, newjoinstyle);
		if (newjoinstyle <= JoinBevel)
		    pGC->joinStyle = newjoinstyle;
		else
		{
		    clientErrorValue = newjoinstyle;
		    error = BadValue;
		}
		break;
	    }
	    case GCFillStyle:
	    {
		unsigned int newfillstyle;
		NEXTVAL(unsigned int, newfillstyle);
		if (newfillstyle <= FillOpaqueStippled)
		    pGC->fillStyle = newfillstyle;
		else
		{
		    clientErrorValue = newfillstyle;
		    error = BadValue;
		}
		break;
	    }
	    case GCFillRule:
	    {
		unsigned int newfillrule;
		NEXTVAL(unsigned int, newfillrule);
		if (newfillrule <= WindingRule)
		    pGC->fillRule = newfillrule;
		else
		{
		    clientErrorValue = newfillrule;
		    error = BadValue;
		}
		break;
	    }
	    case GCTile:
	    {
		XID newpix = 0;
		if (pUnion)
		{
		    NEXT_PTR(PixmapPtr, pPixmap);
		}
		else
		{
		    NEXTVAL(XID, newpix);
		    pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
					newpix, RT_PIXMAP, SecurityReadAccess);
		}
		if (pPixmap)
		{
		    if ((pPixmap->drawable.depth != pGC->depth) ||
			(pPixmap->drawable.pScreen != pGC->pScreen))
		    {
			error = BadMatch;
		    }
		    else
		    {
			pPixmap->refcnt++;
			if (!pGC->tileIsPixel)
			    (* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap);
			pGC->tileIsPixel = FALSE;
			pGC->tile.pixmap = pPixmap;
		    }
		}
		else
		{
		    clientErrorValue = newpix;
		    error = BadPixmap;
		}
		break;
	    }
	    case GCStipple:
	    {
		XID newstipple = 0;
		if (pUnion)
		{
		    NEXT_PTR(PixmapPtr, pPixmap);
		}
		else
		{
		    NEXTVAL(XID, newstipple)
		    pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
				newstipple, RT_PIXMAP, SecurityReadAccess);
		}
		if (pPixmap)
		{
		    if ((pPixmap->drawable.depth != 1) ||
			(pPixmap->drawable.pScreen != pGC->pScreen))
		    {
			error = BadMatch;
		    }
		    else
		    {
			pPixmap->refcnt++;
			if (pGC->stipple)
			    (* pGC->pScreen->DestroyPixmap)(pGC->stipple);
			pGC->stipple = pPixmap;
		    }
		}
		else
		{
		    clientErrorValue = newstipple;
		    error = BadPixmap;
		}
		break;
	    }
	    case GCTileStipXOrigin:
		NEXTVAL(INT16, pGC->patOrg.x);
		break;
	    case GCTileStipYOrigin:
		NEXTVAL(INT16, pGC->patOrg.y);
		break;
	    case GCFont:
    	    {
		FontPtr	pFont;
		XID newfont = 0;
		if (pUnion)
		{
		    NEXT_PTR(FontPtr, pFont);
		}
		else
		{
		    NEXTVAL(XID, newfont)
		    pFont = (FontPtr)SecurityLookupIDByType(client, newfont,
						RT_FONT, SecurityReadAccess);
		}
		if (pFont)
		{
		    pFont->refcnt++;
		    if (pGC->font)
    		        CloseFont(pGC->font, (Font)0);
		    pGC->font = pFont;
		 }
		else
		{
		    clientErrorValue = newfont;
		    error = BadFont;
		}
		break;
	    }
	    case GCSubwindowMode:
	    {
		unsigned int newclipmode;
		NEXTVAL(unsigned int, newclipmode);
		if (newclipmode <= IncludeInferiors)
		    pGC->subWindowMode = newclipmode;
		else
		{
		    clientErrorValue = newclipmode;
		    error = BadValue;
		}
		break;
	    }
	    case GCGraphicsExposures:
    	    {
		unsigned int newge;
		NEXTVAL(unsigned int, newge);
		if (newge <= xTrue)
		    pGC->graphicsExposures = newge;
		else
		{
		    clientErrorValue = newge;
		    error = BadValue;
		}
		break;
	    }
	    case GCClipXOrigin:
		NEXTVAL(INT16, pGC->clipOrg.x);
		break;
	    case GCClipYOrigin:
		NEXTVAL(INT16, pGC->clipOrg.y);
		break;
	    case GCClipMask:
	    {
		Pixmap pid = 0;
		int    clipType = 0;

		if (pUnion)
		{
		    NEXT_PTR(PixmapPtr, pPixmap);
		}
		else
		{
		    NEXTVAL(Pixmap, pid)
		    if (pid == None)
		    {
			clipType = CT_NONE;
			pPixmap = NullPixmap;
		    }
		    else
		        pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
					pid, RT_PIXMAP, SecurityReadAccess);
		}

		if (pPixmap)
		{
		    if ((pPixmap->drawable.depth != 1) ||
			(pPixmap->drawable.pScreen != pGC->pScreen))
		    {
			error = BadMatch;
		    }
		    else
		    {
			clipType = CT_PIXMAP;
			pPixmap->refcnt++;
		    }
		}
		else if (!pUnion && (pid != None))
		{
		    clientErrorValue = pid;
		    error = BadPixmap;
		}
		if(error == Success)
		{
		    (*pGC->funcs->ChangeClip)(pGC, clipType,
					      (pointer)pPixmap, 0);
		}
		break;
	    }
	    case GCDashOffset:
		NEXTVAL(INT16, pGC->dashOffset);
		break;
	    case GCDashList:
	    {
		CARD8 newdash;
		NEXTVAL(CARD8, newdash);
		if (newdash == 4)
		{
		    if (pGC->dash != DefaultDash)
		    {
			xfree(pGC->dash);
			pGC->numInDashList = 2;
			pGC->dash = DefaultDash;
		    }
		}
		else if (newdash != 0)
 		{
		    unsigned char *dash;

		    dash = (unsigned char *)xalloc(2 * sizeof(unsigned char));
		    if (dash)
		    {
			if (pGC->dash != DefaultDash)
			    xfree(pGC->dash);
			pGC->numInDashList = 2;
			pGC->dash = dash;
			dash[0] = newdash;
			dash[1] = newdash;
		    }
		    else
			error = BadAlloc;
		}
 		else
		{
		   clientErrorValue = newdash;
		   error = BadValue;
		}
		break;
	    }
	    case GCArcMode:
	    {
		unsigned int newarcmode;
		NEXTVAL(unsigned int, newarcmode);
		if (newarcmode <= ArcPieSlice)
		    pGC->arcMode = newarcmode;
		else
		{
		    clientErrorValue = newarcmode;
		    error = BadValue;
		}
		break;
	    }
	    default:
		clientErrorValue = maskQ;
		error = BadValue;
		break;
	}
    } /* end while mask && !error */

    if (pGC->fillStyle == FillTiled && pGC->tileIsPixel)
    {
	if (!CreateDefaultTile (pGC))
	{
	    pGC->fillStyle = FillSolid;
	    error = BadAlloc;
	}
    }
    (*pGC->funcs->ChangeGC)(pGC, maskQ);
    return error;
}
// Listview dispatcher
ULONG LIBFUNC listview_dispatch(
	REG(a0, Class *cl),
	REG(a2, Object *obj),
	REG(a1, Msg msg))
{
	ListViewData *data=0;
	struct Gadget *gadget=0;
	ULONG retval=0;

	// Get gadget and data pointers
	if (obj)
	{
		gadget=(struct Gadget *)obj;
		data=INST_DATA(cl,obj);
	}

	// Look at method
	switch (msg->MethodID)
	{
		// Create a new instance
		case OM_NEW:

			// Create superclass instance
			if ((retval=DoSuperMethodA(cl,obj,msg)))
			{
				struct TagItem *tags,*tag;
				short a;
				struct Image *image;
				struct TextAttr *attr;

				// Get pointer to our gadget and instance data
				gadget=(struct Gadget *)retval;
				data=INST_DATA(cl,(APTR)retval);

				// Initialise data
				data->dims=*(struct IBox *)&gadget->LeftEdge;
				NewList(&data->boopsi_list);
				data->sel=-1;
				data->last_selection=-1;

				// Initialise mapping tags
				data->scroll_map[0].ti_Tag=PGA_Top;
				data->scroll_map[0].ti_Data=DLV_Top;
				data->scroll_map[1].ti_Tag=TAG_END;
				data->arrow_up_map[0].ti_Tag=GA_ID;
				data->arrow_up_map[0].ti_Data=DLV_ScrollUp;
				data->arrow_up_map[1].ti_Tag=TAG_END;
				data->arrow_down_map[0].ti_Tag=GA_ID;
				data->arrow_down_map[0].ti_Data=DLV_ScrollDown;
				data->arrow_down_map[1].ti_Tag=TAG_END;

				// Get taglist
				tags=((struct opSet *)msg)->ops_AttrList;

				// Get width of scroller
				data->scroller_width=GetTagData(DLV_ScrollWidth,16,tags);

				// Flags
				if (FindTagItem(DLV_ShowSelected,tags))
					data->flags|=LVF_SHOW_SELECTED;
				if (GetTagData(DLV_ThinBorder,0,tags))
					data->flags|=LVF_THIN_BORDER;
				if (GetTagData(DLV_MultiSelect,0,tags))
					data->flags|=LVF_MULTI_SELECT;
				else
				if (GetTagData(DLV_Check,0,tags))
					data->flags|=LVF_SELECTED_CHECK;
				else
				if ((a=GetTagData(DLV_ShowChecks,0,tags)))
				{
					data->flags|=LVF_SHOW_CHECKS;
					if (a==2) data->flags|=LVF_NO_HIGHLIGHT;
				}
				if (GetTagData(DLV_Highlight,0,tags))
					data->flags|=LVF_SELECTED_HIGH;
				if (GetTagData(DLV_ReadOnly,0,tags))
					data->flags|=LVF_READ_ONLY;
				if (GetTagData(DLV_NoScroller,0,tags))
				{
					data->flags|=LVF_NO_SCROLLER;
					data->scroller_width=0;
				}
				else
				if (GetTagData(DLV_ScrollLeft,0,tags))
					data->flags|=LVF_SCROLLER_LEFT;
				if (GetTagData(DLV_TopJustify,0,tags))
					data->flags|=LVF_TOP_JUSTIFY;
				if (GetTagData(DLV_RightJustify,0,tags))
					data->flags|=LVF_RIGHT_JUSTIFY;
				if ((a=GetTagData(DLV_DragNotify,0,tags)))
				{
					data->flags|=LVF_DRAG_NOTIFY;
					if (a==2) data->flags|=LVF_NO_VERT_SCROLL;
				}
				data->layout_flags=GetTagData(DLV_Flags,PLACETEXT_ABOVE,tags);
				if (GetTagData(DLV_ShowFilenames,0,tags))
					data->flags|=LVF_SHOW_FILENAMES;
				if (GetTagData(DLV_ShowSeparators,0,tags))
					data->flags|=LVF_SHOW_SEPARATORS;

				// Get title
				if ((tag=FindTagItem(GA_Text,tags)))
				{
					char *ptr;
					short pos=0;

					// Get pointer to title
					if ((ptr=(char *)tag->ti_Data))
					{
						data->title_uscore=-1;

						// Copy title string, look for underscore
						while (*ptr && pos<78)
						{
							// Underscore?
							if (*ptr=='_')
							{
								// Remember position, skip over it
								data->title_uscore=pos;
							}

							// Otherwise, store
							else data->title[pos++]=*ptr;
							++ptr;
						}
						data->title[pos]=0;
					}
				}

				// Get font to use
				if ((attr=(struct TextAttr *)GetTagData(GTCustom_TextAttr,0,tags)))
				{
					if ((data->list_font=OpenFont(attr)))
						data->flags|=LVF_GOT_FONT;
				}
				if (!data->list_font) data->list_font=((struct GfxBase *)GfxBase)->DefaultFont;

				// Arrow height
				data->arrow_height=data->list_font->tf_YSize-2;
				if (data->arrow_height<10) data->arrow_height=10;

				// Fix dimensions
				listview_get_dims(cl,data);
				data->text_height=data->list_font->tf_YSize;

				// Need check mark?
				if (data->flags&(LVF_MULTI_SELECT|LVF_SHOW_CHECKS) ||
					(data->flags&(LVF_SHOW_SELECTED|LVF_SELECTED_CHECK))==(LVF_SHOW_SELECTED|LVF_SELECTED_CHECK))
				{
					// Create check image
					if ((data->check=(struct Image *)NewObject(
						0,"dopusiclass",
						DIA_Type,IM_CHECK,
						IA_Width,13,
						IA_Height,data->text_height-1,
						TAG_END)))
					{
						// Add to boopsi list
						DoMethod((Object *)data->check,OM_ADDTAIL,&data->boopsi_list);
					}
					data->text_offset=23;
				}
				else data->text_offset=2;

				// Scroller needed?
				if (!(data->flags&LVF_NO_SCROLLER))
				{
					// Create scroller
					if ((data->scroller=(struct Gadget *)NewObject(
						0,"propgclass",
						GA_Previous,gadget,
						GA_ID,LVGID_SCROLLER,
						GA_Left,(data->flags&LVF_SCROLLER_LEFT)?data->dims.Left+4:data->dims.Left+data->dims.Width-data->scroller_width+4,
						GA_Top,data->dims.Top+2,
						GA_Width,data->scroller_width-8,
						GA_Height,data->dims.Height-4-(data->arrow_height<<1),
						GA_Disabled,(gadget->Flags&GFLG_DISABLED)?TRUE:FALSE,
						PGA_Freedom,FREEVERT,
						PGA_NewLook, TRUE,
						PGA_Borderless,TRUE,
						PGA_Visible,1,
						PGA_Total,1,
						ICA_TARGET,gadget,
						ICA_MAP,data->scroll_map,
						TAG_END)))
					{
						// Add to boopsi list
						DoMethod((Object *)data->scroller,OM_ADDTAIL,&data->boopsi_list);
					}

					// Create up arrow image
					if ((image=(struct Image *)NewObject(
						0,"dopusiclass",
						IA_Width,data->scroller_dims.Width,
						IA_Height,data->arrow_height,
						DIA_Type,IM_ARROW_UP,
						DIA_ThinBorders,(data->flags&LVF_THIN_BORDER)?TRUE:FALSE,
						TAG_END)))
					{
						// Add to boopsi list
						DoMethod((Object *)image,OM_ADDTAIL,&data->boopsi_list);
					}

					// Create up arrow button
					if ((data->arrows[0]=(struct Gadget *)NewObject(
						0,"buttongclass",
						GA_ID,LVGID_ARROW,
						GA_Previous,data->scroller,
						GA_Left,data->scroller_dims.Left,
						GA_Top,data->scroller_dims.Top+data->scroller_dims.Height,
						GA_Width,data->scroller_dims.Width,
						GA_Height,data->arrow_height,
						GA_Image,image,
						GA_Disabled,(gadget->Flags&GFLG_DISABLED)?TRUE:FALSE,
						ICA_TARGET,gadget,
						ICA_MAP,data->arrow_up_map,
						TAG_END)))
					{
						// Add to boopsi list
						DoMethod((Object *)data->arrows[0],OM_ADDTAIL,&data->boopsi_list);
					}

					// Create down arrow image
					if ((image=(struct Image *)NewObject(
						0,"dopusiclass",
						IA_Width,data->scroller_dims.Width,
						IA_Height,data->arrow_height,
						DIA_Type,IM_ARROW_DOWN,
						DIA_ThinBorders,(data->flags&LVF_THIN_BORDER)?TRUE:FALSE,
						TAG_END)))
					{
						// Add to boopsi list
						DoMethod((Object *)image,OM_ADDTAIL,&data->boopsi_list);
					}

					// Create down arrow button
					if ((data->arrows[1]=(struct Gadget *)NewObject(
						0,"buttongclass",
						GA_ID,LVGID_ARROW,
						GA_Previous,data->arrows[0],
						GA_Left,data->scroller_dims.Left,
						GA_Top,data->scroller_dims.Top+data->scroller_dims.Height+data->arrow_height,
						GA_Width,data->scroller_dims.Width,
						GA_Height,data->arrow_height,
						GA_Image,image,
						GA_Disabled,(gadget->Flags&GFLG_DISABLED)?TRUE:FALSE,
						ICA_TARGET,gadget,
						ICA_MAP,data->arrow_down_map,
						TAG_END)))
					{
						// Add to boopsi list
						DoMethod((Object *)data->arrows[1],OM_ADDTAIL,&data->boopsi_list);
					}
				}
			}
			else break;

		// Fall through to OM_SET


		// Update/Set
		case OM_UPDATE:
		case OM_SET:
			{
				struct TagItem *tag,*tags;
				unsigned short old;
				struct Node *node;
				short item;
				short redraw=0;

				// Get taglist
				tags=((struct opSet *)msg)->ops_AttrList;

				// Make visible?
				if ((tag=FindTagItem(DLV_MakeVisible,tags)))
				{
					short scroll;

					// Remember old top
					old=data->top;

					// Get scroll amount
					scroll=tag->ti_Data-old;

					// Need to scroll?
					if (scroll<0 ||
						scroll>=data->lines)
					{
						// Get scroll amount
						if (scroll>=data->lines)
							scroll-=data->lines-1;

						// Get new top
						data->top+=scroll;

						// Bounds check
						if (data->top>data->count-data->lines)
							data->top=data->count-data->lines;
						if (data->top<0) data->top=0;

						// Redraw?
						if (old!=data->top)
						{
							data->last_sel=-1;
							redraw=2;
						}
					}
				}

				// New top?
				else
				if ((tag=FindTagItem(DLV_Top,tags)))
				{
					// Remember old top
					old=data->top;

					// Get new top
					data->top=tag->ti_Data;

					// Bounds check
					if (data->top>data->count-data->lines)
						data->top=data->count-data->lines;
					if (data->top<0) data->top=0;

					// Redraw?
					if (old!=data->top)
					{
						data->last_sel=-1;
						redraw=2;
					}
				}

				// Scroll up
				else
				if ((tag=FindTagItem(DLV_ScrollUp,tags)))
				{
					// Is this the gadgetup?
					if (msg->MethodID==OM_UPDATE &&
						!(((struct opUpdate *)msg)->opu_Flags&OPUF_INTERIM))
					{
						// Clear scroll count
						data->scroll_count=0;
					}

					// Or is this the second/third scroll (first/second intuitick)?
					else
					if (msg->MethodID==OM_UPDATE &&
						(data->scroll_count==1 || data->scroll_count==2))
					{
						// Throw this away
						++data->scroll_count;
					}

					// Otherwise, check it's valid
					else
					if (tag->ti_Data!=(ULONG)-LVGID_ARROW)
					{
						// Bounds check
						if (data->top>0)
						{
							--data->top;
							data->last_sel=-1;
							redraw=2;
						}

						// Increment scroll count if necessary
						if (msg->MethodID==OM_UPDATE) ++data->scroll_count;
					}
				}

				// Scroll down
				else
				if ((tag=FindTagItem(DLV_ScrollDown,tags)))
				{
					// Is this the gadgetup?
					if (msg->MethodID==OM_UPDATE &&
						!(((struct opUpdate *)msg)->opu_Flags&OPUF_INTERIM))
					{
						// Clear scroll count
						data->scroll_count=0;
					}

					// Or is this the second/third scroll (first/second intuitick)?
					else
					if (msg->MethodID==OM_UPDATE &&
						(data->scroll_count==1 || data->scroll_count==2))
					{
						// Throw this away
						++data->scroll_count;
					}

					// Otherwise, check it's valid
					else
					if (tag->ti_Data!=(ULONG)-LVGID_ARROW)
					{
						// Bounds check
						if (data->top<data->count-data->lines)
						{
							++data->top;
							data->last_sel=-1;
							redraw=2;
						}

						// Increment scroll count if necessary
						if (msg->MethodID==OM_UPDATE) ++data->scroll_count;
					}
				}

				// New labels
				if ((tag=FindTagItem(DLV_Labels,tags)))
				{
					// clear top item
					data->top_item=0;

					// Store new label pointer
					data->labels=(struct List *)tag->ti_Data;

					// Detached list?
					if (data->labels==(struct List *)~0)
						data->flags|=LVF_DETACHED;

					// No list
					else
					if (data->labels==0)
					{
						// Clear detach flag
						data->count=0;
						data->flags&=~LVF_DETACHED;
						redraw=1;
					}

					// Valid list
					else
					{
						// Count items
						for (data->count=0,node=data->labels->lh_Head;
							node->ln_Succ;
							data->count++,node=node->ln_Succ);

						// Bounds check top
						if (data->top+data->lines>data->count)
							data->top=data->count-data->lines;
						if (data->top<0) data->top=0;

						// Check selection for out-of-bounds
						if (data->sel>data->count-1) data->sel=-1;

						// Clear detach flag
						data->flags&=~LVF_DETACHED;
						redraw=1;
					}
				}

				// Selected
				if ((tag=FindTagItem(DLV_Selected,tags)) ||
					(tag=FindTagItem(DLV_SelectPrevious,tags)) ||
					(tag=FindTagItem(DLV_SelectNext,tags)) ||
					(tag=FindTagItem(DLV_PageUp,tags)) ||
					(tag=FindTagItem(DLV_PageDown,tags)) ||
					(tag=FindTagItem(DLV_Home,tags)) ||
					(tag=FindTagItem(DLV_End,tags)))
				{
					// Store old
					old=data->sel;

					// Get new selected
					if (tag->ti_Tag==DLV_Selected)
					{
						data->sel=tag->ti_Data;
					}
					else
					if (tag->ti_Tag==DLV_SelectPrevious)
					{
						if (data->sel>0) --data->sel;
					}
					else
					if (tag->ti_Tag==DLV_SelectNext)
					{
						++data->sel;
					}
					else
					if (tag->ti_Tag==DLV_PageUp)
					{
						if (data->sel==data->top)
							data->sel-=data->lines-1;
						else
							data->sel=data->top;
						if (data->sel<0) data->sel=0;
					}
					else
					if (tag->ti_Tag==DLV_PageDown)
					{
						if (data->sel==data->top+data->lines-1)
							data->sel+=data->lines-1;
						else
							data->sel=data->top+data->lines-1;
					}
					else
					if (tag->ti_Tag==DLV_Home)
					{
						data->sel=0;
					}
					else
					if (tag->ti_Tag==DLV_End)
					{
						data->sel=data->count-1;
					}

					// Bounds check
					if (data->sel>data->count-1) data->sel=data->count-1;
					if (data->sel<0) data->sel=-1;

					// Changed?
					if (data->sel!=old && !(gadget->Flags&GFLG_DISABLED))
					{
						// Save selection
						if (!redraw)
						{
							data->last_sel=data->last_selection;
							redraw=2;
						}
						data->last_selection=data->sel;

						// Send notify
						DoMethod(obj,OM_NOTIFY,0,((struct opSet *)msg)->ops_GInfo,0);
					}
				}

				// Disabled (set only)
				if (msg->MethodID==OM_SET &&
					(tag=FindTagItem(GA_Disabled,tags)))
				{
					// Different to current state?
					if ((tag->ti_Data && !(gadget->Flags&GFLG_DISABLED)) ||
						(!tag->ti_Data && gadget->Flags&GFLG_DISABLED))
					{
						struct TagItem distags[2];
						short a;

						// Fill out disable tags
						distags[0].ti_Tag=GA_Disabled;
						distags[0].ti_Data=tag->ti_Data;
						distags[1].ti_Tag=TAG_DONE;

						// Set state of slider
						if (data->scroller)
						{
							DoMethod(
								(Object *)data->scroller,
								OM_SET,
								distags,
								((struct opSet *)msg)->ops_GInfo);

							// And arrows
							for (a=0;a<2;a++)
								DoMethod(
									(Object *)data->arrows[a],
									OM_SET,
									distags,
									((struct opSet *)msg)->ops_GInfo);

							// Set flag to say disable state changed
							if (!tag->ti_Data)
								data->flags|=LVF_DISABLE_CHANGE;
						}

						// Change disable state and redraw
						gadget->Flags^=GFLG_DISABLED;
						redraw=1;
					}
				}

				// Get top item
				if (!data->labels) data->top_item=0;
				else
				if (!(data->flags&LVF_DETACHED) && data->labels)
				{
					for (node=data->labels->lh_Head,item=0;
						node->ln_Succ && item<data->top;
						node=node->ln_Succ,item++);
					data->top_item=node;
				}

				// Do we need to redraw the list?
				if (msg->MethodID==OM_SET || msg->MethodID==OM_UPDATE)
				{
					if (redraw && !(data->flags&LVF_DETACHED))
					{
						struct RastPort *rp;

						// Get rastport
						if ((rp=ObtainGIRPort(((struct opSet *)msg)->ops_GInfo)))
						{
							// Send redraw
							DoMethod(
								obj,
								GM_RENDER,
								((struct opSet *)msg)->ops_GInfo,
								rp,
								(redraw==2)?GREDRAW_UPDATE:GREDRAW_REDRAW);
							ReleaseGIRPort(rp);
						}
					}
				}
			}
			break;


		// Get an attribute
		case OM_GET:
			{
				struct opGet *get;

				// Get get message
				get=(struct opGet *)msg;

				// Default to ok
				retval=1;

				// Look at attribute
				switch (get->opg_AttrID)
				{
					// Selected
					case DLV_Selected:
						*get->opg_Storage=(ULONG)data->last_selection;
						break;

					// Top
					case DLV_Top:
						*get->opg_Storage=(ULONG)data->top;
						break;

					// Lines
					case DLV_Lines:
						*get->opg_Storage=(ULONG)data->lines;
						break;

					// Labels
					case DLV_Labels:
						*get->opg_Storage=(ULONG)data->labels;
						break;

					// Get line from coordinates
					case DLV_GetLine:
						{
							unsigned short x,y;
							struct gpInput fake;

							// Get coordinates
							x=((*get->opg_Storage)>>16)&0xffff;
							y=(*get->opg_Storage)&0xffff;

							// Fake gpInput
							fake.gpi_Mouse.X=x-gadget->LeftEdge;
							fake.gpi_Mouse.Y=y-gadget->TopEdge;

							// Get selection
							*get->opg_Storage=(ULONG)listview_get_sel(cl,gadget,data,&fake,0);
						}
						break;

					// Draw a line from the listview
					case DLV_DrawLine:
						{
							ListViewDraw *draw=(ListViewDraw *)*get->opg_Storage;

							// Draw line
							listview_draw_item(
								cl,
								gadget,
								draw->rp,
								draw->drawinfo,
								data,
								draw->node,
								draw->line,
								&draw->box);
						}
						break;

					// Other
					default:
						retval=DoSuperMethodA(cl,obj,msg);
						break;
				}
			}
			break;


		// Kill an instance
		case OM_DISPOSE:
			{
				APTR object_ptr;
				Object *object;

 				// Free BOOPSI objects
				object_ptr=data->boopsi_list.lh_Head;
				while ((object=NextObject((APTR)&object_ptr)))
					DisposeObject(object);

				// Free font
				if (data->flags&LVF_GOT_FONT)
					CloseFont(data->list_font);

				retval=DoSuperMethodA(cl,obj,msg);
			}
			break;


		// Render gadget
		case GM_RENDER:

			// Cache DrawInfo
			data->draw_info=((struct gpRender *)msg)->gpr_GInfo->gi_DrInfo;

			// If a full redraw, clear double-click time
			if (((struct gpRender *)msg)->gpr_Redraw==GREDRAW_REDRAW)
				data->seconds=0;

			// Show gadget
			listview_render(cl,gadget,data,(struct gpRender *)msg);
			break;


		// Hit test
		case GM_HITTEST:
			{
				struct gpHitTest *test;

				// Get test pointer
				test=(struct gpHitTest *)msg;

				// See if we're hit
				if (test->gpht_Mouse.X>=data->text_dims.Left-gadget->LeftEdge &&
					test->gpht_Mouse.Y>=data->text_dims.Top-gadget->TopEdge &&
					test->gpht_Mouse.X<data->text_dims.Left+data->text_dims.Width-gadget->LeftEdge &&
					test->gpht_Mouse.Y<data->text_dims.Top+data->text_dims.Height-gadget->TopEdge)
				{
					retval=GMR_GADGETHIT;
				}
			}
			break;


		// Notify
		case OM_NOTIFY:

			// Drag notify?
			if (data->flags&LVF_DRAG_FLAG)
			{
				// Fill out tags
				data->notify_tags[0].ti_Tag=DLV_DragNotify;
				data->notify_tags[0].ti_Data=data->drag_sel;
				data->notify_tags[1].ti_Tag=GA_ID;
				data->notify_tags[1].ti_Data=gadget->GadgetID;
				data->notify_tags[2].ti_Tag=GA_Left;
				data->notify_tags[2].ti_Data=data->text_dims.Left;
				data->notify_tags[3].ti_Tag=GA_Top;
				data->notify_tags[3].ti_Data=data->text_dims.Top+
					UMult32(data->drag_sel-data->top,data->text_height);
				data->notify_tags[4].ti_Tag=GA_Width;
				data->notify_tags[4].ti_Data=data->text_dims.Width;
				data->notify_tags[5].ti_Tag=GA_Height;
				data->notify_tags[5].ti_Data=data->text_height;
				data->notify_tags[6].ti_Tag=GA_RelRight;
				data->notify_tags[6].ti_Data=data->drag_x_position;
				data->notify_tags[7].ti_Tag=GA_RelBottom;
				data->notify_tags[7].ti_Data=data->drag_y_position;
				data->notify_tags[8].ti_Tag=DLV_Top;
				data->notify_tags[8].ti_Data=data->top;
				data->notify_tags[9].ti_Tag=DLV_Object;
				data->notify_tags[9].ti_Data=(ULONG)gadget;
				data->notify_tags[10].ti_Tag=TAG_END;

				// Clear flag
				data->flags&=~LVF_DRAG_FLAG;
			}

			// Otherwise normal notify
			else
			{
				ULONG seconds,micros;

				// Fill out tags
				data->notify_tags[0].ti_Tag=DLV_Selected;
				data->notify_tags[0].ti_Data=data->last_selection;
				data->notify_tags[1].ti_Tag=GA_ID;
				data->notify_tags[1].ti_Data=gadget->GadgetID;
				data->notify_tags[2].ti_Tag=TAG_END;

				// Get current time
				CurrentTime(&seconds,&micros);

				// Double-click?
				if (data->click_sel==data->last_selection &&
					DoubleClick(data->seconds,data->micros,seconds,micros))
				{
					// Set double-click flag
					data->notify_tags[2].ti_Tag=DLV_DoubleClick;
					data->notify_tags[2].ti_Data=TRUE;
					data->notify_tags[3].ti_Tag=TAG_END;

					// Clear double-click
					data->seconds=0;
				}

				// Otherwise
				else
				{
					// Remember double-click
					data->seconds=seconds;
					data->micros=micros;
					data->click_sel=data->last_selection;
				}
			}

			// Send message
			DoSuperMethod(cl,obj,OM_NOTIFY,data->notify_tags,((struct opUpdate *)msg)->opu_GInfo,0);
			break;


		// Go (in)active/Handle input
		case GM_GOACTIVE:
		case GM_GOINACTIVE:
		case GM_HANDLEINPUT:
			{
				struct gpInput *input;
				short redraw=0;

				// Get input pointer
				input=(struct gpInput *)msg;

				// Go active?
				if (input->MethodID==GM_GOACTIVE)
				{
					// Default is not to activate
					retval=GMR_NOREUSE;

					// Ok to go active?
					if (!(gadget->Flags&GFLG_DISABLED) && input->gpi_IEvent)
					{
						// Left button down and valid list?
						if (input->gpi_IEvent->ie_Code==SELECTDOWN &&
							data->labels &&
							!(data->flags&(LVF_READ_ONLY|LVF_DETACHED)))
						{
							short sel;

							// Get selection
							if ((sel=listview_get_sel(cl,gadget,data,input,0))>-1)
							{
								// Ok to activate
								retval=GMR_MEACTIVE;

								// Store current top
								data->last_top=data->top;

								// Remember x and y click-offset
								data->drag_x_position=input->gpi_Mouse.X-
									(data->text_dims.Left-data->dims.Left);
								data->drag_y_position=input->gpi_Mouse.Y-
									(data->text_dims.Top-data->dims.Top)-
									UMult32(sel-data->top,data->text_height);

								// Change?
								if (data->sel!=sel ||
									!(data->flags&LVF_SHOW_SELECTED) ||
									(data->flags&LVF_SELECTED_CHECK))
								{
									// New selection
									data->last_sel=data->last_selection;
									data->sel=sel;
									redraw=1;
								}

								// Set selected flag
								gadget->Flags|=GFLG_SELECTED;
							}
						}
					}
				}

				// Go inactive?
				else
				if (msg->MethodID==GM_GOINACTIVE)
				{
					// Clear selected flag
					gadget->Flags&=~GFLG_SELECTED;

					// If we're showing selection with checks, we need to redraw last selection
					if ((data->flags&(LVF_SHOW_SELECTED|LVF_SELECTED_CHECK))==(LVF_SHOW_SELECTED|LVF_SELECTED_CHECK))
						data->last_sel=data->last_selection;
					redraw=1;

					// Save this selection
					data->last_selection=data->sel;

					// Send notify
					DoMethod(obj,OM_NOTIFY,0,((struct gpInput *)msg)->gpi_GInfo,0);

					// Clear cancel flag
					data->flags&=~LVF_CANCEL;
				}

				// Handle input
				else
				{
					// Default return value
					retval=GMR_MEACTIVE;

					// Is it a mouse event?
					if (input->gpi_IEvent->ie_Class==IECLASS_RAWMOUSE)
					{
						// Look at mouse code
						switch (input->gpi_IEvent->ie_Code)
						{
							// Left button up
							case SELECTUP:
								{
									// Set return code
									*input->gpi_Termination=data->sel;

									// Gadget processing finished
									retval=GMR_NOREUSE|GMR_VERIFY;
									data->flags|=LVF_CANCEL;

									// Multi-selection?
									if (data->flags&LVF_MULTI_SELECT)
									{
										struct Node *node;
										short count;

										// Get this node
										for (node=data->labels->lh_Head,count=0;
											node->ln_Succ && count<data->sel;
											node=node->ln_Succ,count++);

										// Did we get it?
										if (node && node->ln_Succ)
										{
											// Save old selection
											data->last_sel=data->sel;

											// Toggle selection
											node->lve_Flags^=LVEF_SELECTED;
											redraw=1;
										}
									}
								}
								break;

							// No button; mouse moved
							case IECODE_NOBUTTON:
								{
									short sel;

									// Is mouse outside of lister?
									if (input->gpi_Mouse.X<0 ||
										input->gpi_Mouse.X>=data->list_dims.Width)
									{
										// Drag notify?
										if (data->flags&LVF_DRAG_NOTIFY)
										{
											// Valid selection?
											if (data->sel>-1)
											{
												// Notify drag
												data->flags|=LVF_DRAG_FLAG;
												data->drag_sel=data->sel;

												// Will fall through to MENUDOWN (if NO_VERT_SCROLL)
												if (!(data->flags&LVF_NO_VERT_SCROLL))
												{
													retval=GMR_NOREUSE;
													data->flags|=LVF_CANCEL;
													break;
												}
											}
											else break;
										}
										else break;
									}

									// Get selection
									else
									if ((sel=listview_get_sel(cl,gadget,data,input,1))>-1 ||
										(sel==-1 && (data->flags&LVF_NO_VERT_SCROLL)))
									{
										// Change?
										if (data->sel!=sel || sel==-1)
										{
											// Clear double-click
											data->seconds=0;

											// No vertical scroll?
											if (data->flags&LVF_NO_VERT_SCROLL)
											{
												// Drag notify?
												if (data->flags&LVF_DRAG_NOTIFY)
												{
													// Notify drag
													data->flags|=LVF_DRAG_FLAG;
													data->drag_sel=data->sel;

													// Will fall through to MENUDOWN
												}
												else break;
											}

											// Otherwise
											else
											{
												// Save old selection
												data->last_sel=data->sel;

												// New selection
												data->sel=sel;
												redraw=1;
												break;
											}
										}
										else break;
									}

									else break;
								}

							// Right button does cancel
							case MENUDOWN:
								{
									// Gadget processing finished
									retval=GMR_NOREUSE;
									data->flags|=LVF_CANCEL;

									// Show selected?
									if (data->flags&LVF_SHOW_SELECTED)
									{
										// Restore last selection
										data->last_sel=data->sel;
										data->sel=data->last_selection;

										// Does top need to change?
										if (data->top!=data->last_top)
										{
											short item;

											data->top=data->last_top;
											data->last_sel=-1;

											for (data->top_item=data->labels->lh_Head,item=0;
												data->top_item->ln_Succ && item<data->top;
												data->top_item=data->top_item->ln_Succ,item++);
										}

										redraw=1;
									}
								}
								break;
						}
					}

					// Or a timer event
					else
					if (input->gpi_IEvent->ie_Class==IECLASS_TIMER)
					{
						short sel;

						// Get selection
						if ((sel=listview_get_sel(cl,gadget,data,input,2))>-1)
						{
							// Change?
							if (data->sel!=sel)
							{
								// Save old selection
								data->last_sel=data->sel;

								// New selection
								data->sel=sel;

								// Do we have to scroll?
								if (sel<data->top)
								{
									if (data->top>0)
									{
										// Scroll up
										--data->top;
										data->top_item=data->top_item->ln_Pred;

										// Redraw the list
										data->last_sel=-1;
										redraw=1;
									}
								}
								else
								if (sel>=data->top+data->lines)
								{
									if (data->top+data->lines<data->count)
									{
										// Scroll down
										++data->top;
										data->top_item=data->top_item->ln_Succ;

										// Redraw the list
										data->last_sel=-1;
										redraw=1;
									}
								}
								else redraw=1;
							}
						}
					}
				}

				// Redraw needed?
				if (redraw)
				{
					struct RastPort *rp;

					// Get rastport
					if ((rp=ObtainGIRPort(input->gpi_GInfo)))
					{
						// Send redraw
						DoMethod(obj,GM_RENDER,input->gpi_GInfo,rp,GREDRAW_UPDATE);
						ReleaseGIRPort(rp);
					}
				}
			}
			break;


		// Resize
		case GM_RESIZE:

			// Handle the resize
			listview_resize(cl,gadget,data,(struct gpResize *)msg);
			break;


		// Unknown method
		default:
			retval=DoSuperMethodA(cl,obj,msg);
			break;
	}

	return retval;
}
main(int argc, char *argv[])
{
    unsigned char str[256];
    int i;
    int j;
    struct RastPort rp;
    unsigned char *pp;
    struct BitMap bm = {
	256, 	/* bytes per row */
	8,	/* rows */
	0,	/* flags */
	1,	/* depth */
	0,	/* pad */
	0 	/* planes */
	};
    struct TextAttr ta;
    struct TextFont *tf;
    struct FontRequester *fr;
    struct TagItem frtags[] = {
	ASL_Hail, (ULONG)"NetBSD font choices",
	ASL_Width, 640,
	ASL_Height, 400,
	ASL_LeftEdge, 10,
	ASL_TopEdge, 10,
	ASL_OKText, (ULONG)"Dump",
	ASL_CancelText, (ULONG)"Cancel",
	ASL_FontName, (ULONG)"topaz.font",
	ASL_FontHeight, 8L,
	ASL_FontStyles, FS_NORMAL,
	ASL_FuncFlags, FONF_STYLES | FONF_FIXEDWIDTH,
	TAG_DONE
	    };

    /* Let the user pick a font to dump */
    if (fr = (struct FontRequester *)
	AllocAslRequest(ASL_FontRequest, frtags)) {
	if (!AslRequest(fr, NULL)) {
	    FreeAslRequest(fr);
	    fprintf(stderr, "User requested exit\n");
	    exit (0);
	}
	ta.ta_Name = (STRPTR)malloc(strlen(fr->fo_Attr.ta_Name));
	strcpy(ta.ta_Name, fr->fo_Attr.ta_Name);
	ta.ta_YSize = fr->fo_Attr.ta_YSize;
	ta.ta_Style = fr->fo_Attr.ta_Style;
	ta.ta_Flags = fr->fo_Attr.ta_Flags;
	FreeAslRequest(fr);
    } else {
	fprintf(stderr, "Can't allocate Font Requestor\n");
	exit (1);
    }

    /* Open the selected font */
    tf = (struct TextFont *)OpenDiskFont (&ta);
    if (! tf) {
	fprintf (stderr, "Can't open font: %s\n", ta.ta_Name);
	exit (1);
    }
#ifdef DEBUG
    fprintf(stderr, "Information on selected font:\n");
    fprintf(stderr, "Name=%s\n", ta.ta_Name);
    fprintf(stderr, "Height=%d tf_Style=%x tf_Flags=%x Width=%d Baseline=%d\n",
	    tf->tf_YSize, tf->tf_Style, tf->tf_Flags, tf->tf_XSize, tf->tf_Baseline);
#endif

    /* Check for NetBSD restrictions */
    if (tf->tf_Flags & FPF_PROPORTIONAL) {
	fprintf(stderr, "NetBSD does not support proportional fonts\n");
	exit (1);
    }
    if (tf->tf_XSize > NetBSDwidth) {
	fprintf(stderr, "NetBSD does not support fonts wider than %d pixels\n", NetBSDwidth);
	exit (1);
    }

    /* Allocate area to render font in */
    InitBitMap(&bm, 1, 256 * NetBSDwidth, tf->tf_YSize);
    InitRastPort (&rp);
    rp.BitMap = &bm;
    bm.Planes[0] = pp = AllocRaster (256 * NetBSDwidth, tf->tf_YSize);
    if (!pp) {
	fprintf (stderr, "Can't allocate raster!\n");
	exit (1);
    }

    /* Initialize string to be rendered */
    for (i = 32; i < 256; i++) {
	str[i - 32] = i;
    }

    /* Render string with selected font */
    SetFont (&rp, tf);
    SetSoftStyle(&rp, ta.ta_Style ^ tf->tf_Style,
		 FSF_BOLD | FSF_UNDERLINED | FSF_ITALIC);
    Move (&rp, 0, tf->tf_Baseline);
    ClearEOL(&rp);
    if (tf->tf_XSize != NetBSDwidth) {
	/* right-justify char in cell */
	Move (&rp, NetBSDwidth - tf->tf_XSize, tf->tf_Baseline);
	/* Narrow font, put each character in space of normal font */
	for (i = 0; i < (256 - 32); i++) {
	    Text (&rp, &str[i], 1);
	    Move (&rp, rp.cp_x + (NetBSDwidth - tf->tf_XSize), rp.cp_y);
	}
    } else {
	Text (&rp, str, 256 - 32);
    }

    /* Dump them.. */
    printf ("/* Generated automatically by fontdumper.c. *DONT* distribute\n");
    printf ("   this file, it may contain information Copyright by Commodore!\n");
    printf ("\n");
    printf ("   Font: %s/%d\n", ta.ta_Name, tf->tf_YSize);
    printf (" */\n\n");

    printf ("unsigned char kernel_font_width  = %d;\n", tf->tf_XSize);
    printf ("unsigned char kernel_font_height = %d;\n", tf->tf_YSize);
    printf ("unsigned char kernel_font_baseline = %d;\n", tf->tf_Baseline);
    printf ("short         kernel_font_boldsmear = %d;\n", tf->tf_BoldSmear);
    printf ("unsigned char kernel_font_lo = 32;\n");
    printf ("unsigned char kernel_font_hi = 255;\n\n");

    printf ("unsigned char kernel_cursor[] = {\n");
    for (j = 0; j < (tf->tf_YSize -1); j++) {
	printf ("0xff, ");
    }
    printf ("0xff };\n\n");

    printf ("unsigned char kernel_font[] = {\n");
    for (i = 0; i < 256 - 32; i++) {
	printf ("/* %c */", i + 32);
	for (j = 0; j < tf->tf_YSize; j++) {
	    printf (" 0x%02x,", pp[i+j*256]);
	    }
	printf ("\n");
    }
    printf ("};\n");

    CloseFont (tf);
    FreeRaster (pp, 256 * NetBSDwidth, tf->tf_YSize);
    return (0);
}
Beispiel #27
0
_X_EXPORT int
CopyGC(register GC *pgcSrc, register GC *pgcDst, register BITS32 mask)
{
    register BITS32	index2;
    BITS32		maskQ;
    int 		error = 0;

    if (pgcSrc == pgcDst)
	return Success;
    pgcDst->serialNumber |= GC_CHANGE_SERIAL_BIT;
    pgcDst->stateChanges |= mask;
    maskQ = mask;
    while (mask)
    {
	index2 = (BITS32) lowbit (mask);
	mask &= ~index2;
	switch (index2)
	{
	    case GCFunction:
		pgcDst->alu = pgcSrc->alu;
		break;
	    case GCPlaneMask:
		pgcDst->planemask = pgcSrc->planemask;
		break;
	    case GCForeground:
		pgcDst->fgPixel = pgcSrc->fgPixel;
		break;
	    case GCBackground:
		pgcDst->bgPixel = pgcSrc->bgPixel;
		break;
	    case GCLineWidth:
		pgcDst->lineWidth = pgcSrc->lineWidth;
		break;
	    case GCLineStyle:
		pgcDst->lineStyle = pgcSrc->lineStyle;
		break;
	    case GCCapStyle:
		pgcDst->capStyle = pgcSrc->capStyle;
		break;
	    case GCJoinStyle:
		pgcDst->joinStyle = pgcSrc->joinStyle;
		break;
	    case GCFillStyle:
		pgcDst->fillStyle = pgcSrc->fillStyle;
		break;
	    case GCFillRule:
		pgcDst->fillRule = pgcSrc->fillRule;
		break;
	    case GCTile:
		{
		    if (EqualPixUnion(pgcDst->tileIsPixel,
				      pgcDst->tile,
				      pgcSrc->tileIsPixel,
				      pgcSrc->tile))
		    {
			break;
		    }
		    if (!pgcDst->tileIsPixel)
			(* pgcDst->pScreen->DestroyPixmap)(pgcDst->tile.pixmap);
		    pgcDst->tileIsPixel = pgcSrc->tileIsPixel;
		    pgcDst->tile = pgcSrc->tile;
		    if (!pgcDst->tileIsPixel)
		       pgcDst->tile.pixmap->refcnt++;
		    break;
		}
	    case GCStipple:
		{
		    if (pgcDst->stipple == pgcSrc->stipple)
			break;
		    if (pgcDst->stipple)
			(* pgcDst->pScreen->DestroyPixmap)(pgcDst->stipple);
		    pgcDst->stipple = pgcSrc->stipple;
		    if (pgcDst->stipple)
			pgcDst->stipple->refcnt ++;
		    break;
		}
	    case GCTileStipXOrigin:
		pgcDst->patOrg.x = pgcSrc->patOrg.x;
		break;
	    case GCTileStipYOrigin:
		pgcDst->patOrg.y = pgcSrc->patOrg.y;
		break;
	    case GCFont:
		if (pgcDst->font == pgcSrc->font)
		    break;
		if (pgcDst->font)
		    CloseFont(pgcDst->font, (Font)0);
		if ((pgcDst->font = pgcSrc->font) != NullFont)
		    (pgcDst->font)->refcnt++;
		break;
	    case GCSubwindowMode:
		pgcDst->subWindowMode = pgcSrc->subWindowMode;
		break;
	    case GCGraphicsExposures:
		pgcDst->graphicsExposures = pgcSrc->graphicsExposures;
		break;
	    case GCClipXOrigin:
		pgcDst->clipOrg.x = pgcSrc->clipOrg.x;
		break;
	    case GCClipYOrigin:
		pgcDst->clipOrg.y = pgcSrc->clipOrg.y;
		break;
	    case GCClipMask:
		(* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
		break;
	    case GCDashOffset:
		pgcDst->dashOffset = pgcSrc->dashOffset;
		break;
	    case GCDashList:
		if (pgcSrc->dash == DefaultDash)
		{
		    if (pgcDst->dash != DefaultDash)
		    {
			xfree(pgcDst->dash);
			pgcDst->numInDashList = pgcSrc->numInDashList;
			pgcDst->dash = pgcSrc->dash;
		    }
		}
		else
		{
		    unsigned char *dash;
		    unsigned int i;

		    dash = (unsigned char *)xalloc(pgcSrc->numInDashList *
						   sizeof(unsigned char));
		    if (dash)
		    {
			if (pgcDst->dash != DefaultDash)
			    xfree(pgcDst->dash);
			pgcDst->numInDashList = pgcSrc->numInDashList;
			pgcDst->dash = dash;
			for (i=0; i<pgcSrc->numInDashList; i++)
			    dash[i] = pgcSrc->dash[i];
		    }
		    else
			error = BadAlloc;
		}
		break;
	    case GCArcMode:
		pgcDst->arcMode = pgcSrc->arcMode;
		break;
	    default:
		clientErrorValue = maskQ;
		error = BadValue;
		break;
	}
    }
    if (pgcDst->fillStyle == FillTiled && pgcDst->tileIsPixel)
    {
	if (!CreateDefaultTile (pgcDst))
	{
	    pgcDst->fillStyle = FillSolid;
	    error = BadAlloc;
	}
    }
    (*pgcDst->funcs->CopyGC) (pgcSrc, maskQ, pgcDst);
    return error;
}
Beispiel #28
0
static ULONG EqualizeItems(struct MenuItem *firstitem, struct MenuItem *lastitem,
    	    	    	   struct Image *amikeyimage, struct VisualInfo *vi,
			   struct GadToolsBase_intern * GadToolsBase)
{
    struct MenuItem 	*item;
    struct TextExtent    te;
    WORD    	    	 minx = 0, maxwidth = 0, maxrightstuffwidth = 0;

    if (!firstitem) return 0;

    /* Calc. the max. width of item text/image (+ checkmark image)
       Calc. the min. item->LeftEdge */

    for(item = firstitem; item && (item != lastitem); item = item->NextItem)
    {
        if (item->LeftEdge < minx) minx = item->LeftEdge;
	if (item->Width > maxwidth) maxwidth = item->Width;
    }

    /* Calc. the max. width of AmigaKey/CommandString/">>" */

    FontExtent(vi->vi_dri->dri_Font, &te);

    for(item = firstitem; item && (item != lastitem); item = item->NextItem)
    {
        WORD width = 0;

	if (item->Flags & COMMSEQ)
	{
	    width = te.te_Width;

	    if (item->Flags & ITEMTEXT)
	    {
        	struct TextFont  *font;
		struct IntuiText *it = (struct IntuiText *)item->ItemFill;

		if (it->ITextFont)
		{
        	    if ((font = OpenFont(it->ITextFont)))
        	    {
		    	struct TextExtent e;
			
			FontExtent(font, &e);
			
        	        width = e.te_Width;
        	        CloseFont(font);
        	    }
		}
	    }

            width += amikeyimage->Width +
		     AMIGAKEY_KEY_SPACING;

        }
	else if (item->Flags & ITEMTEXT)
	{
	    struct IntuiText *it = (struct IntuiText *)item->ItemFill;
	    struct IntuiText *it2;

	    if ((it2 = it->NextText))
	    {
	        it2->FrontPen = it->FrontPen;
		it2->BackPen  = it->BackPen;
		it2->DrawMode = it->DrawMode;
		it2->TopEdge  = it->TopEdge;

		/* save width also in it->LeftEdge. Will be used below to
		   calc. x position */

	        width = it2->LeftEdge = MyIntuiTextLength(vi, it2, GadToolsBase);
	    }
	}

	if (width > maxrightstuffwidth) maxrightstuffwidth = width;

    } /* for(item = firstitem; item; item = item->NextItem) */

    /* Calc. x coordinate of command strings and ">>"'s and submenu pos. */

    if (maxrightstuffwidth)
    {
        maxwidth += maxrightstuffwidth + TEXT_AMIGAKEY_SPACING;

	for(item = firstitem; item && (item != lastitem); item = item->NextItem)
	{
	    struct MenuItem *subitem;

	    if (item->Flags & ITEMTEXT)
	    {
	        struct IntuiText *it = (struct IntuiText *)item->ItemFill;

		if ((it = it->NextText))
		{
		    /* it->LeftEdge contains the pixel width. see above */

		    it->LeftEdge = minx + maxwidth - it->LeftEdge - ITEXT_EXTRA_RIGHT;
		}
	    }

	    for(subitem = item->SubItem; subitem; subitem = subitem->NextItem)
	    {
	        subitem->LeftEdge += (maxwidth - maxrightstuffwidth);
	    }
	}

    } /* if (maxrightstuffwidth) */

    /* Make all items have the same width and set also the width and the
       drawinfo of barlabel images */

    for(item = firstitem; item && (item != lastitem); item = item->NextItem)
    {
        item->Width = maxwidth;

	if(!(item->Flags & ITEMTEXT))
	{
	    struct Image *im = (struct Image *)item->ItemFill;

	    if (is_menubarlabelclass_image(im, GadToolsBase))
	    {
		struct TagItem image_tags [] =
		{
		    {IA_Width	    , maxwidth - ITEXT_EXTRA_LEFT - ITEXT_EXTRA_RIGHT	},
		    {SYSIA_DrawInfo , (IPTR)vi->vi_dri					},
		    {TAG_DONE			    	    	    	    	    	}
		};

		SetAttrsA(im, image_tags);

	    }
	}
    }

    return (ULONG)maxwidth;
}
Beispiel #29
0
static BOOL LayOutReq (struct AHIAudioModeRequesterExt *req, struct TextAttr *TextAttr)
{
  struct Gadget *gad;
  struct NewGadget ng;

  struct TextAttr *gadtextattr;
  struct TextFont *font;
  LONG   fontwidth,buttonheight,buttonwidth,pixels;
  struct IntuiText intuitext = {1,0,JAM1,0,0,NULL,NULL,NULL};
  LONG  sliderlevels,sliderlevel;
  LONG  selected;

  selected=GetSelected(req);
  GetSliderAttrs(req,&sliderlevels,&sliderlevel);

// Calculate gadget area
  req->gx=req->Window->BorderLeft+4;
  req->gy=req->Window->BorderTop+2;
  req->gw=req->Window->Width-req->gx-(req->Window->BorderRight+4);
  req->gh=req->Window->Height-req->gy-(req->Window->BorderBottom+2);

  if(req->Gadgets)
  {
    RemoveGList(req->Window,req->Gadgets,-1);
    FreeGadgets(req->Gadgets);
    SetAPen(req->Window->RPort,0);
    SetDrMd(req->Window->RPort,JAM1);
    EraseRect(req->Window->RPort, req->Window->BorderLeft, req->Window->BorderTop,
        req->Window->Width-req->Window->BorderRight-1,req->Window->Height-req->Window->BorderBottom-1);
    RefreshWindowFrame(req->Window);
  }
  req->Gadgets=NULL;
  if((gad=CreateContext(&req->Gadgets)))
  {
    if(TextAttr)
      gadtextattr=TextAttr;
    else
      gadtextattr=req->Window->WScreen->Font;

    if((font=OpenFont(gadtextattr)))
    {
      fontwidth=font->tf_XSize;
      CloseFont(font);
    }
    else
      return FALSE;

    buttonheight=gadtextattr->ta_YSize+6;
    intuitext.ITextFont=gadtextattr;
    intuitext.IText=req->PositiveText;
    buttonwidth=IntuiTextLength(&intuitext);
    intuitext.IText=req->NegativeText;
    pixels=IntuiTextLength(&intuitext);
    buttonwidth=max(pixels,buttonwidth);
    buttonwidth+=4+fontwidth;

// Create gadgets and check if they fit
    // Do the two buttons fit?
    if(2*buttonwidth > req->gw)
      return FALSE;
    ng.ng_TextAttr=gadtextattr;
    ng.ng_VisualInfo=req->vi;
    ng.ng_UserData=req;
// OK button
    ng.ng_LeftEdge=req->gx;
    ng.ng_TopEdge=req->gy+req->gh-buttonheight;
    ng.ng_Width=buttonwidth;
    ng.ng_Height=buttonheight;
    ng.ng_GadgetText=req->PositiveText;
    ng.ng_GadgetID=OKBUTTON;
    ng.ng_Flags=PLACETEXT_IN;
    gad=CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
// Cancel button
    ng.ng_LeftEdge=req->gx+req->gw-ng.ng_Width;
    ng.ng_GadgetText=req->NegativeText;
    ng.ng_GadgetID=CANCELBUTTON;
    gad=CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
// Frequency
    if(req->Flags & freqgad)
    {
      intuitext.IText = GetString(msgReqFrequency, req->Catalog);
      pixels=IntuiTextLength(&intuitext)+INTERWIDTH;
      if(pixels+MINSLIDERWIDTH+INTERWIDTH+FREQLEN2*fontwidth > req->gw)
        return FALSE;
      ng.ng_Width=req->gw-pixels-INTERWIDTH-FREQLEN2*fontwidth;
      ng.ng_LeftEdge=req->gx+pixels;
      ng.ng_TopEdge-=2+buttonheight;
      ng.ng_GadgetText = GetString(msgReqFrequency, req->Catalog);
      ng.ng_GadgetID=FREQSLIDER;
      ng.ng_Flags=PLACETEXT_LEFT;
      gad=CreateGadget(SLIDER_KIND,gad,&ng,
          GTSL_Min,0,
          GTSL_Max,sliderlevels-1,
          GTSL_Level,sliderlevel,
          GTSL_LevelFormat, (ULONG) FREQTEXT2,
          GTSL_MaxLevelLen,FREQLEN2,
          GTSL_LevelPlace,PLACETEXT_RIGHT,
          GTSL_DispFunc, (ULONG) m68k_IndexToFrequency,
          GA_RelVerify,TRUE,
          GA_Disabled,!sliderlevels || (req->tempAudioID == AHI_DEFAULT_ID),
          TAG_DONE);
      req->slidergadget=gad;   // Save for HadleReq()...
    }
// ListView
    if((ng.ng_Height=ng.ng_TopEdge-2-req->gy) < buttonheight)
      return FALSE;
    ng.ng_LeftEdge=req->gx;
    ng.ng_TopEdge=req->gy;
    ng.ng_Width=req->gw;
    ng.ng_GadgetText=NULL,
    ng.ng_GadgetID=LISTVIEW;
    ng.ng_Flags=PLACETEXT_ABOVE;
    gad=CreateGadget(LISTVIEW_KIND,gad,&ng,
        GTLV_ScrollWidth,(fontwidth>8 ? fontwidth*2 : 18),
        GTLV_Labels, (ULONG) req->list,
        GTLV_ShowSelected,NULL,
        ((selected == ~0) || (GadToolsBase->lib_Version >= 39) ? TAG_IGNORE : GTLV_Top),selected,
        (selected == ~0 ? TAG_IGNORE : GTLV_MakeVisible),selected,
        GTLV_Selected,selected,
        TAG_DONE);
    req->listviewgadget=gad;   // Save for HadleReq()...

    if(!gad)
      return FALSE;
  }
  else
    return FALSE;

  AddGList(req->Window,req->Gadgets,~0,-1,NULL);
  RefreshGList(req->Gadgets,req->Window,NULL,-1);
  GT_RefreshWindow(req->Window,NULL);

  return TRUE;
}
Beispiel #30
0
BOOL layoutmenuitems(struct MenuItem * firstitem,
                     struct VisualInfo * vi,
                     struct TagItem * taglist,
                     struct GadToolsBase_intern * GadToolsBase)
{
    struct Menu     	* menu;
    struct MenuItem 	* menuitem = firstitem;
    struct MenuItem 	* equalizeitem = firstitem;
    struct Image 	* amikeyimage, * chkimage;
    struct TextExtent	te;    
    ULONG 		curX = 0;
    ULONG 		curY = 0;
    WORD    	    	numcolumns = 1;
    
    amikeyimage = (struct Image *)GetTagData(GTMN_AmigaKey, 0, taglist);
    if (!amikeyimage) amikeyimage = vi->vi_dri->dri_AmigaKey;

    chkimage = (struct Image *)GetTagData(GTMN_Checkmark, 0, taglist);
    if (!chkimage) chkimage = vi->vi_dri->dri_CheckMark;

    FontExtent(vi->vi_dri->dri_Font, &te);
    
    while (NULL != menuitem)
    {
	ULONG addwidth = 0;
	ULONG addleft = 0;

	menuitem->LeftEdge = curX;
	menuitem->TopEdge  = curY;

	if (0 != (menuitem->Flags & CHECKIT))
	{
	    /*
	    ** A checkmark will appear on the left.
	    */

	    addleft  += chkimage->Width + CHECKMARK_TEXT_SPACING;
	    addwidth += chkimage->Width + CHECKMARK_TEXT_SPACING;
	}

	if (0 != (menuitem->Flags & ITEMTEXT))
	{
	    /*
	    ** Text
	    */
	    struct IntuiText * it = (struct IntuiText *)menuitem->ItemFill;
	    struct TagItem   * ti;

	    if (NULL == it)
        	return FALSE;

	    if (NULL != (ti = FindTagItem(GTMN_FrontPen, taglist)))
	    {
        	it->FrontPen = ti->ti_Data;
	    }
	    else
	    {
        	it->FrontPen = vi->vi_dri->dri_Pens[BARDETAILPEN];
	    }

	    it->ITextFont = (struct TextAttr *)GetTagData(GTMN_TextAttr,
                                                	  0,
                                                	  taglist);

	    it->LeftEdge = ITEXT_EXTRA_LEFT + addleft;
	    it->TopEdge = ITEXT_EXTRA_TOP;

	    menuitem->Width = MyIntuiTextLength(vi, it, GadToolsBase) +
      			      addwidth + ITEXT_EXTRA_LEFT + ITEXT_EXTRA_RIGHT;

	   /*
	    ** Calculate the height menu item.
	    */
	    if (NULL == it->ITextFont)
	    {
        	/*
        	** No font is provided, so I will work with the screen font.
        	*/
        	menuitem->Height = vi->vi_dri->dri_Font->tf_YSize + ITEXT_EXTRA_TOP + ITEXT_EXTRA_BOTTOM;
	    }
	    else
	    {
        	struct TextFont * font;

        	if (NULL != (font = OpenFont(it->ITextFont)))
        	{
        	    menuitem->Height = font->tf_YSize + ITEXT_EXTRA_TOP + ITEXT_EXTRA_BOTTOM;
        	    CloseFont(font);
        	}
        	else
        	    return FALSE;
	    }

	} /* if (0 != (menuitem->Flags & ITEMTEXT)) */
	else
	{
	    /*
	    ** Image
	    */
	    struct Image * im = (struct Image *)menuitem->ItemFill;

	    if (NULL == im) return FALSE;

	    if (is_menubarlabelclass_image(im, GadToolsBase))
	    {
    	    	menuitem->Width = 10;
        	menuitem->Height = 7;

	    }
	    else
	    {

		menuitem->Width  = im->Width + addwidth + IMAGE_EXTRA_LEFT + IMAGE_EXTRA_RIGHT;
		menuitem->Height = im->Height + IMAGE_EXTRA_TOP + IMAGE_EXTRA_BOTTOM;
		im->LeftEdge = IMAGE_EXTRA_LEFT + addleft;
		im->TopEdge = IMAGE_EXTRA_TOP;
	    }

	} /* if (0 != (menuitem->Flags & ITEMTEXT)) else ... */

        curY += menuitem->Height;

	/*
	** In case this menu becomes too high it will have more columns.
	*/

	if (curY > vi->vi_screen->Height)
	{
	    ULONG width;

	    width = EqualizeItems(equalizeitem, menuitem, amikeyimage, vi, GadToolsBase);
	    equalizeitem = menuitem;

	    curY = 0;
	    curX += width + MENU_COLUMN_SPACING;
	    menuitem->LeftEdge = curX;
	    menuitem->TopEdge  = curY;

	    curY += menuitem->Height;
	    
	    numcolumns++;
	}

	/*
	** Process the next menu item
	*/
	menuitem = menuitem->NextItem;

    } /* while (NULL != menuitem) */

    EqualizeItems(equalizeitem, NULL, amikeyimage, vi, GadToolsBase);

    menu = (struct Menu *)GetTagData(GTMN_Menu, 0, taglist);
    if (menu && (menu->FirstItem == firstitem))
    {
    	/* Make sure the menu box is at least as large as the menu title,
	   otherwise it looks ugly */

 	WORD menuwidth, minx, maxx, titlewidth, prevy = -1, col = 1;
	
	minx = 32767;
	maxx = -32768;
	
	for(menuitem = firstitem; menuitem; menuitem = menuitem->NextItem)
	{
	    if (menuitem->LeftEdge < minx) minx = menuitem->LeftEdge;
	    if (menuitem->LeftEdge + menuitem->Width - 1 > maxx) maxx = menuitem->LeftEdge + menuitem->Width - 1;	    
	}
	
	menuwidth = maxx - minx + 1;
	titlewidth = TextLength(&vi->vi_screen->RastPort, menu->MenuName, strlen(menu->MenuName));
	
	if (titlewidth > menuwidth)
	{
	    WORD extrawidth = (titlewidth - menuwidth + numcolumns / 2) / numcolumns;

	    for(menuitem = firstitem; menuitem; menuitem = menuitem->NextItem)
	    {
	    	struct MenuItem *subitem;
		
	    	if (menuitem->TopEdge < prevy) col++;
		prevy = menuitem->TopEdge;
		
	    	menuitem->LeftEdge += (col - 1) * extrawidth;
    	    	menuitem->Width += extrawidth;
		
		if (menuitem->Flags & ITEMTEXT)
		{
		    struct IntuiText *it = (struct IntuiText *)menuitem->ItemFill;
		    
		    if ((it = it->NextText))
		    {
		    	it->LeftEdge += extrawidth;
		    } 
		}
		else
		{
	    	    struct Image *im = (struct Image *)menuitem->ItemFill;
		    
		    if (is_menubarlabelclass_image(im, GadToolsBase))
		    {
		    	im->Width += extrawidth;
		    }
		}
		
		if ((subitem = menuitem->SubItem))
		{
		    while(subitem)
		    {
		    	subitem->LeftEdge += extrawidth;
			subitem = subitem->NextItem;
		    }
		}
				
	    } /* for(menuitem = firstitem; menuitem; menuitem = menuitem->NextItem) */
	    
	} /* if (titlewidth > menuwidth) */
	
    } /* if (menu && (menu->FirstItem == firstitem)) */
    
    
    return TRUE;
}