properlyish distinguish between primary+clipboard x11 selections. Fix possible font crash. Fix possible QC weirdness with uri_get callbacks unexpectedly stomping globals.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5321 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2018-10-14 16:16:34 +00:00
parent 2cdbe035df
commit 487201eeec
14 changed files with 218 additions and 135 deletions

View file

@ -2021,7 +2021,10 @@ static int Con_DrawConsoleLines(console_t *con, conline_t *l, int sx, int ex, in
x = selex;
selex = selsx;
selsx = x;
con->flags &= ~CONF_BACKSELECTION;
}
else
con->flags |= CONF_BACKSELECTION;
// selsy *= Font_CharHeight();
// seley *= Font_CharHeight();
selsy += y;
@ -2594,10 +2597,16 @@ void Con_DrawConsole (int lines, qboolean noback)
con_current->mousecursor[0] = mousecursor_x;
con_current->mousecursor[1] = mousecursor_y;
if (!(con_current->flags & CONF_KEEPSELECTION))
{
con_current->selstartline = NULL;
con_current->selendline = NULL;
}
selactive = Key_GetConsoleSelectionBox(con_current, &selsx, &selsy, &selex, &seley);
if ((con_current->flags & CONF_KEEPSELECTION) && con_current->selstartline && con_current->selendline)
selactive = -1;
Font_BeginString(font_console, x, y, &x, &y);
Font_BeginString(font_console, selsx, selsy, &selsx, &selsy);
Font_BeginString(font_console, selex, seley, &selex, &seley);

View file

@ -1071,6 +1071,7 @@ void Key_DefaultLinkClicked(console_t *con, char *text, char *info)
}
}
#define Key_IsTouchScreen() false
void Key_ConsoleRelease(console_t *con, int key, unsigned int unicode)
{
char *buffer;
@ -1085,10 +1086,28 @@ void Key_ConsoleRelease(console_t *con, int key, unsigned int unicode)
con->flags &= ~CONF_KEEPSELECTION;
else
con->flags |= CONF_KEEPSELECTION;
if (con->userdata)
{
if (con->flags & CONF_BACKSELECTION)
{
con->userline = con->selendline;
con->useroffset = con->selendoffset;
}
else
{
con->userline = con->selstartline;
con->useroffset = con->selstartoffset;
}
}
}
con->buttonsdown = CB_NONE;
buffer = Con_CopyConsole(con, true, false); //don't keep markup if we're copying to the clipboard
if (buffer)
{
Sys_SaveClipboard(CBT_SELECTION, buffer);
Z_Free(buffer);
}
}
if (key == K_MOUSE1 && con->buttonsdown == CB_SCROLL)
{
@ -1172,7 +1191,7 @@ void Key_ConsoleRelease(console_t *con, int key, unsigned int unicode)
buffer = Con_CopyConsole(con, true, false); //don't keep markup if we're copying to the clipboard
if (!buffer)
return;
Sys_SaveClipboard(CBT_SELECTION, buffer);
Sys_SaveClipboard(CBT_CLIPBOARD, buffer);
Z_Free(buffer);
}
if (con->buttonsdown == CB_CLOSE)
@ -1327,7 +1346,7 @@ static void Key_ConsolePaste(void *ctx, char *utf8)
if (utf8)
Key_EntryInsert(line, linepos, utf8);
}
qboolean Key_EntryLine(unsigned char **line, int lineoffset, int *linepos, int key, unsigned int unicode)
qboolean Key_EntryLine(console_t *con, unsigned char **line, int lineoffset, int *linepos, int key, unsigned int unicode)
{
qboolean alt = keydown[K_LALT] || keydown[K_RALT];
qboolean ctrl = keydown[K_LCTRL] || keydown[K_RCTRL];
@ -1415,21 +1434,29 @@ qboolean Key_EntryLine(unsigned char **line, int lineoffset, int *linepos, int k
//beware that windows translates ctrl+c and ctrl+v to a control char
if (((unicode=='C' || unicode=='c' || unicode==3) && ctrl) || (ctrl && key == K_INS))
{
if (con && (con->flags & CONF_KEEPSELECTION))
{ //copy selected text to the system clipboard
char *buffer = Con_CopyConsole(con, true, false);
if (buffer)
{
Sys_SaveClipboard(CBT_CLIPBOARD, buffer);
Z_Free(buffer);
}
return true;
}
//copy the entire input line if there's nothing selected.
Sys_SaveClipboard(CBT_CLIPBOARD, *line);
return true;
}
if (((unicode=='V' || unicode=='v' || unicode==22) && ctrl) || (shift && key == K_INS))
{
Sys_Clipboard_PasteText(CBT_CLIPBOARD, Key_ConsolePaste, line);
/*
char *clipText = Sys_GetClipboard();
if (clipText)
{
Key_EntryInsert(line, linepos, clipText);
Sys_CloseClipboard(clipText);
if (key == K_MOUSE3)
{ //middle-click to paste from the unixy primary buffer.
Sys_Clipboard_PasteText(CBT_SELECTION, Key_ConsolePaste, line);
return true;
}
*/
if (((unicode=='V' || unicode=='v' || unicode==22) && ctrl) || (shift && key == K_INS))
{ //ctrl+v to paste from the windows-style clipboard.
Sys_Clipboard_PasteText(CBT_CLIPBOARD, Key_ConsolePaste, line);
return true;
}
@ -1598,7 +1625,14 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode)
{
if (con->redirect && con->redirect(con, unicode, key))
return true;
if (Key_IsTouchScreen())
{ //just scroll the console up/down
con->buttonsdown = CB_SCROLL;
}
else
{ //selecting text. woo.
con->buttonsdown = CB_SELECT;
}
con->flags &= ~CONF_KEEPSELECTION;
}
}
@ -1681,6 +1715,10 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode)
}
#endif
if (key == K_MOUSE3) //mousewheel click/middle button
{
}
//console does not have any way to accept input, so don't try giving it any.
if (!con->linebuffered)
{
@ -1822,7 +1860,7 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode)
cmd_completion_t *c;
char *txt = key_lines[edit_line];
char *guess = Cmd_CompleteCommand(*txt=='/'?txt+1:txt, true, true, con_commandmatch, NULL);
Key_EntryLine(&key_lines[edit_line], 0, &key_linepos, key, unicode);
Key_EntryLine(con, &key_lines[edit_line], 0, &key_linepos, key, unicode);
if (!key_linepos)
con_commandmatch = 0;
else if (guess)
@ -1839,7 +1877,7 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode)
}
}
else
Key_EntryLine(&key_lines[edit_line], 0, &key_linepos, key, unicode);
Key_EntryLine(con, &key_lines[edit_line], 0, &key_linepos, key, unicode);
return true;
}
@ -1897,7 +1935,7 @@ void Key_Message (int key, int unicode)
return;
}
Key_EntryLine(&chat_buffer, 0, &chat_bufferpos, key, unicode);
Key_EntryLine(NULL, &chat_buffer, 0, &chat_bufferpos, key, unicode);
}
//============================================================================

View file

@ -80,6 +80,8 @@ void Sys_Clipboard_PasteText(clipboardtype_t cbt, void (*callback)(void *cb, cha
}
void Sys_SaveClipboard(clipboardtype_t cbt, char *text)
{
if (cbt != CBT_CLIPBOARD)
return; //don't copy on mere selection. windows users won't expect it.
Z_Free(clippy);
clippy = Z_StrDup(text);
}

View file

@ -201,8 +201,9 @@ lame timers. :s
typedef struct cmdtimer_s {
struct cmdtimer_s *next;
float timer;
int level;
char cmdtext[1];
int iarg;
void(*callback)(int iarg, void *data);
char data[1];
} cmdtimer_t;
static cmdtimer_t *cmdtimers;
static void Cmd_ExecuteTimers(void)
@ -215,16 +216,33 @@ static void Cmd_ExecuteTimers(void)
if (t->timer < realtime)
{
*link = t->next;
Cbuf_InsertText(t->cmdtext, t->level, true);
t->callback(t->iarg, t->data);
Z_Free(t);
}
else
link = &t->next;
}
}
void Cmd_AddTimer(float delay, void(*callback)(int iarg, void *data), int iarg, void *data, size_t datasize)
{
cmdtimer_t *n = Z_Malloc(sizeof(*n) + datasize);
n->iarg = iarg;
n->callback = callback;
memcpy(n->data, data, datasize);
n->data[datasize] = 0; //just in case.
n->timer = realtime + delay;
n->next = cmdtimers;
cmdtimers = n;
}
static void Cmd_In_Callback(int iarg, void *data)
{
Cbuf_AddText((char*)data, iarg);
Cbuf_AddText("\n", iarg);
}
static void Cmd_In_f(void)
{
cmdtimer_t *n;
float delay = atof(Cmd_Argv(1));
char *cmd;
if (Cmd_Argc() < 3)
@ -236,15 +254,7 @@ static void Cmd_In_f(void)
cmd = Cmd_Args();
if (ruleset_allow_in.ival || !delay)
{
n = Z_Malloc(sizeof(*n) + strlen(cmd));
strcpy(n->cmdtext, cmd);
n->timer = realtime + delay;
n->level = Cmd_ExecLevel;
n->next = cmdtimers;
cmdtimers = n;
}
Cmd_AddTimer(delay, Cmd_In_Callback, Cmd_ExecLevel, cmd, strlen(cmd));
}
/*

View file

@ -193,3 +193,4 @@ qboolean If_EvaluateBoolean(const char *text, int restriction);
extern cvar_t rcon_level;
void Cmd_AddTimer(float delay, void(*callback)(int iarg, void *data), int iarg, void *data, size_t datasize); //wrong place, gah

View file

@ -5080,7 +5080,7 @@ static void COM_Version_f (void)
#elif defined(Q3CLIENT)
Con_Printf(" Quake3(client)");
#elif defined(Q3BSPS)
Con_Printf(" Quake3(bsp only)");
Con_DPrintf(" ^hQuake3(bsp only)^7");
#else
Con_DPrintf(" ^h(disabled: Quake3)^7");
#endif
@ -5091,7 +5091,7 @@ static void COM_Version_f (void)
#elif defined(Q2CLIENT)
Con_Printf(" Quake2(client)");
#elif defined(Q2BSPS)
Con_Printf(" Quake2(bsp only)");
Con_DPrintf(" ^hQuake2(bsp only)^7");
#else
Con_DPrintf(" ^h(disabled: Quake2)^7");
#endif

View file

@ -131,7 +131,8 @@ typedef struct conline_s {
#define CONF_KEYFOCUSED 32
#define CONF_ISWINDOW 64
#define CONF_NOWRAP 128
#define CONF_KEEPSELECTION 256
#define CONF_KEEPSELECTION 256 //there's text selected, keep it selected.
#define CONF_BACKSELECTION 512 //a hint that the text was selected from the end
typedef struct console_s
{
int id;

View file

@ -606,6 +606,8 @@ static qboolean FS_Manifest_ParseTokens(ftemanifest_t *man)
FS_Manifest_ParsePackage(man, mdt_installation);
else if (!Q_strcasecmp(cmd, "package") || !Q_strcasecmp(cmd, "archivedpackage"))
FS_Manifest_ParsePackage(man, mdt_singlepackage);
else if (!Q_strcasecmp(cmd, "basedir"))
;
else
{
Con_Printf("Unknown token: %s\n", cmd);

View file

@ -458,49 +458,6 @@ int QDECL QCEditor (pubprogfuncs_t *prinst, const char *filename, int *line, int
if (fatal)
return DEBUG_TRACE_ABORT;
return DEBUG_TRACE_OFF; //get lost
{
int i;
char buffer[8192];
char *r;
vfsfile_t *f;
#ifndef CLIENTONLY
SV_EndRedirect();
#endif
if (developer.value && line)
{
f = FS_OpenVFS(filename, "rb", FS_GAME);
}
else
f = NULL; //faster.
if (!f)
{
Q_snprintfz(buffer, sizeof(buffer), "%s/%s", pr_sourcedir.string, filename);
f = FS_OpenVFS(buffer, "rb", FS_GAME);
}
if (!f)
{
if (reason)
Con_Printf("-%s - %i: %s\n", filename, line?*line:*statement, reason);
else
Con_Printf("-%s - %i\n", filename, line?*line:*statement);
}
else
{
for (i = 0; i < *line; i++)
{
VFS_GETS(f, buffer, sizeof(buffer));
}
if ((r = strchr(buffer, '\r')))
{ r[0] = '\n';r[1]='\0';}
Con_Printf("-%s", buffer);
VFS_CLOSE(f);
}
}
if (reason)
return DEBUG_TRACE_ABORT;
//PF_break(NULL);
return DEBUG_TRACE_OVER;
#endif
}
@ -4654,17 +4611,29 @@ void QCBUILTIN PF_uri_unescape (pubprogfuncs_t *prinst, struct globalvars_s *pr
}
#ifdef WEBCLIENT
static void PR_uri_get_callback(struct dl_download *dl)
typedef struct
{
world_t *w = dl->user_ctx;
world_t *w;
float id;
int selfnum;
int spawncount;
int response;
vfsfile_t *file;
} urigetcbctx_t;
static void PR_uri_get_callback2(int iarg, void *data)
{
urigetcbctx_t *ctx = data;
world_t *w = ctx->w;
pubprogfuncs_t *prinst = w->progs;
float id = dl->user_float;
int selfnum = dl->user_num;
float id = ctx->id;
int selfnum = ctx->selfnum;
int replycode = ctx->response;
func_t func;
if (!prinst || dl->user_sequence != w->spawncount)
return;
//make sure the progs vm is still active and okay.
if (prinst && ctx->spawncount == w->spawncount)
{
func = PR_FindFunction(prinst, "URI_Get_Callback", PR_ANY);
if (!func)
Con_Printf("URI_Get_Callback missing\n");
@ -4673,25 +4642,44 @@ static void PR_uri_get_callback(struct dl_download *dl)
int len;
char *buffer;
struct globalvars_s *pr_globals = PR_globals(prinst, PR_CURRENT);
int oldself = *w->g.self;
*w->g.self = selfnum;
G_FLOAT(OFS_PARM0) = id;
G_FLOAT(OFS_PARM1) = (dl->replycode!=200)?dl->replycode:0; //for compat with DP, we change any 200s to 0.
G_FLOAT(OFS_PARM1) = (replycode!=200)?replycode:0; //for compat with DP, we change any 200s to 0.
G_INT(OFS_PARM2) = 0;
if (dl->file)
if (ctx->file)
{
len = VFS_GETLEN(dl->file);
len = VFS_GETLEN(ctx->file);
buffer = malloc(len+1);
buffer[len] = 0;
VFS_READ(dl->file, buffer, len);
VFS_READ(ctx->file, buffer, len);
G_INT(OFS_PARM2) = PR_TempString(prinst, buffer);
free(buffer);
}
PR_ExecuteProgram(prinst, func);
*w->g.self = oldself;
}
}
if (ctx->file)
VFS_CLOSE(ctx->file);
}
static void PR_uri_get_callback(struct dl_download *dl)
{ //we might be sitting on a setmodel etc call (or really anywhere). don't call qc while the qc is already busy.
urigetcbctx_t ctx;
ctx.w = dl->user_ctx;
ctx.id = dl->user_float;
ctx.selfnum = dl->user_num;
ctx.spawncount = dl->user_sequence;
ctx.response = dl->replycode;
ctx.file = dl->file;
dl->file = NULL; //steal the file pointer, so the download code can't close it before we can read it.
//now post it to the timer queue, it'll get processed within a frame, ish, without screwing up any other qc state.
Cmd_AddTimer(0, PR_uri_get_callback2, 0, &ctx, sizeof(ctx));
}
#endif
// uri_get() gets content from an URL and calls a callback "uri_get_callback" with it set as string; an unique ID of the transfer is returned

View file

@ -2622,21 +2622,26 @@ unsigned int Mod_NearestCubeForSurf(msurface_t *surf, denvmap_t *envmap, size_t
size_t n, v;
unsigned int best = ~0;
float bestdist = FLT_MAX, dist;
vec3_t diff, mid;
vec3_t diff, mins, maxs, mid;
if (surf->mesh)
if (surf->mesh && surf->mesh->numvertexes)
{
VectorClear(mid);
for (v = 0; v < surf->mesh->numvertexes; v++)
VectorAdd(mid, surf->mesh->xyz_array[v], mid);
VectorScale(mid, 1.0/surf->mesh->numvertexes, mid);
VectorCopy(surf->mesh->xyz_array[0], mins);
VectorCopy(surf->mesh->xyz_array[0], maxs);
for (v = 1; v < surf->mesh->numvertexes; v++)
AddPointToBounds(surf->mesh->xyz_array[0], mins, maxs);
VectorAvg(mins, maxs, mid);
for (n = 0; n < nenvmap; n++)
{
VectorSubtract(mid, envmap[n].origin, diff);
VectorSubtract(envmap[n].origin, mid, diff);
#if 1
//axial distance
dist = min(min(fabs(diff[0]), fabs(diff[1])), fabs(diff[2]));
dist = fabs(diff[0]);
if (dist > fabs(diff[1]))
dist = fabs(diff[1]);
if (dist > fabs(diff[2]))
dist = fabs(diff[2]);
#else
//radial distance (squared)
dist = DotProduct(diff,diff);
@ -2740,7 +2745,7 @@ void Mod_FindCubemaps_f(void)
if (nenvmap)
{
qsort(envmap, nenvmap, sizeof(*envmap), envmapsort);
qsort(envmap, nenvmap, sizeof(*envmap), envmapsort); //sort them by size
if (ZF_ReallocElements((void**)&envmapidx, &nenvmapidx, cl.worldmodel->numsurfaces, sizeof(*envmapidx)))
{
for(i = 0; i < cl.worldmodel->numsurfaces; i++)

View file

@ -1099,8 +1099,14 @@ static struct charcache_s *Font_TryLoadGlyph(font_t *f, CHARIDXTYPE charidx)
if (qface->ft.activeheight!=qface->ft.actualsize)
{
//I'm just going to assume full-height raster glyphs here. I'm sure I'll be proven wrong some time but w/e.
int nh = f->charheight;
int nw = (bm->width*nh)/bm->rows;
int nw, nh;
if (bm->rows)
{
nh = f->charheight;
nw = (bm->width*nh)/bm->rows;
}
else
nw = nh = 0;
if (bm->pixel_mode == FT_PIXEL_MODE_BGRA)
{
unsigned int *out = alloca(nw*nh*sizeof(*out));

View file

@ -5841,7 +5841,7 @@ void Shader_DefaultScript(const char *shortname, shader_t *s, const void *args)
f++;
Shader_ReadShader(s, (void*)f, 0);
}
};
}
void Shader_DefaultBSPLM(const char *shortname, shader_t *s, const void *args)
{

View file

@ -1284,8 +1284,7 @@ static qboolean XI2_Init(void)
//qboolean isPermedia = false;
extern qboolean sys_gracefulexit;
#define SYS_CLIPBOARD_SIZE 512
char clipboard_buffer[SYS_CLIPBOARD_SIZE];
char *clipboard_buffer[2];
/*-----------------------------------------------------------------------*/
@ -2545,8 +2544,18 @@ static void GetEvent(void)
Atom xa_text = x11.pXInternAtom(vid_dpy, "TEXT", false); //selection owner decides encoding (and we pick UTF-8)
Atom xa_targets = x11.pXInternAtom(vid_dpy, "TARGETS", false);
Atom xa_supportedtargets[] = {xa_u8string, xa_l1string, xa_text, xa_targets/*, xa_multiple, xa_timestamp*/};
char *cliptext = NULL;
memset(&rep, 0, sizeof(rep));
if (event.xselectionrequest.selection == x11.pXInternAtom(vid_dpy, "PRIMARY", false))
cliptext = clipboard_buffer[CBT_SELECTION];
else if (event.xselectionrequest.selection == x11.pXInternAtom(vid_dpy, "CLIPBOARD", false))
cliptext = clipboard_buffer[CBT_CLIPBOARD];
if (!cliptext) //err, nothing in the clipboard buffer... that's not meant to happen.
cliptext = "";
if (event.xselectionrequest.property == None) //no property sets a property matching the target atom, as a fallback.
event.xselectionrequest.property = event.xselectionrequest.target;
if (event.xselectionrequest.property == None)
event.xselectionrequest.property = x11.pXInternAtom(vid_dpy, "foobar2000", false);
if (event.xselectionrequest.property != None && event.xselectionrequest.target == xa_targets)
@ -2556,13 +2565,13 @@ static void GetEvent(void)
}
else if (event.xselectionrequest.property != None && (event.xselectionrequest.target == xa_u8string || event.xselectionrequest.target == xa_text))
{ //UTF8_STRING or TEXT (which we choose to use utf-8 as our charset)
x11.pXChangeProperty(vid_dpy, event.xselectionrequest.requestor, event.xselectionrequest.property, event.xselectionrequest.target, 8, PropModeReplace, (void*)clipboard_buffer, strlen(clipboard_buffer));
x11.pXChangeProperty(vid_dpy, event.xselectionrequest.requestor, event.xselectionrequest.property, event.xselectionrequest.target, 8, PropModeReplace, (void*)cliptext, strlen(cliptext));
rep.xselection.property = event.xselectionrequest.property;
}
else if (event.xselectionrequest.property != None && event.xselectionrequest.target == xa_l1string)
{ //STRING == latin1. convert as needed.
char latin1[SYS_CLIPBOARD_SIZE];
char *in = clipboard_buffer;
char *latin1 = alloca(strlen(cliptext)+1); //may shorten
char *in = cliptext;
int c = 0;
int err;
while (*in && c < sizeof(latin1))
@ -3739,7 +3748,7 @@ void Sys_Clipboard_PasteText(clipboardtype_t clipboardtype, void (*callback)(voi
x11paste.prop = x11.pXInternAtom(vid_dpy, "_FTE_PASTE", false);
clipboardowner = x11.pXGetSelectionOwner(vid_dpy, x11paste.clipboard);
if (clipboardowner == vid_window)
callback(ctx, clipboard_buffer); //we own it? no point doing round-robin stuff.
callback(ctx, clipboard_buffer[clipboardtype]); //we own it? no point doing round-robin stuff.
else if (clipboardowner != None && clipboardowner != vid_window)
{
x11.pXConvertSelection(vid_dpy, x11paste.clipboard, xa_string, x11paste.prop, vid_window, CurrentTime);
@ -3751,7 +3760,7 @@ void Sys_Clipboard_PasteText(clipboardtype_t clipboardtype, void (*callback)(voi
callback(ctx, NULL); //nothing to paste (the window that owned it sucks
}
else
callback(ctx, clipboard_buffer); //if we're not using x11 then just instantly call the callback
callback(ctx, clipboard_buffer[clipboardtype]); //if we're not using x11 then just instantly call the callback
}
static qboolean X11_Clipboard_Notify(XSelectionEvent *xselection)
{ //called once XConvertSelection completes
@ -3806,14 +3815,22 @@ static qboolean X11_Clipboard_Notify(XSelectionEvent *xselection)
void Sys_SaveClipboard(clipboardtype_t clipboardtype, char *text)
{
Q_strncpyz(clipboard_buffer, text, SYS_CLIPBOARD_SIZE);
free(clipboard_buffer[clipboardtype]);
clipboard_buffer[clipboardtype] = strdup(text);
if(vid_dpy)
{
Atom xa_clipboard = x11.pXInternAtom(vid_dpy, "PRIMARY", false);
x11.pXSetSelectionOwner(vid_dpy, xa_clipboard, vid_window, CurrentTime);
//Set both clipboards for now. Because x11 is kinda annoying.
Atom xa_clipboard;
switch(clipboardtype)
{
case CBT_SELECTION:
xa_clipboard = x11.pXInternAtom(vid_dpy, "PRIMARY", false);
break;
case CBT_CLIPBOARD:
xa_clipboard = x11.pXInternAtom(vid_dpy, "CLIPBOARD", false);
break;
default:
return;
}
x11.pXSetSelectionOwner(vid_dpy, xa_clipboard, vid_window, CurrentTime);
}
}

View file

@ -596,9 +596,13 @@ void QDECL World_LinkEdict (world_t *w, wedict_t *ent, qboolean touch_triggers)
if (!ent->v->solid)
ent->solidsize = ES_SOLID_BSP;
else// if (1)///*ent->v->modelindex || */ent->v->model)
else
{
model_t *mod = w->Get_CModel(w, ent->v->modelindex);
model_t *mod;
if (ent->v->solid == SOLID_BSP)
mod = w->Get_CModel(w, ent->v->modelindex);
else
mod = NULL;
if (mod && mod->type == mod_brush)
ent->solidsize = ES_SOLID_BSP;
else