diff --git a/engine/client/console.c b/engine/client/console.c index 16d66ee07..e8629a947 100644 --- a/engine/client/console.c +++ b/engine/client/console.c @@ -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; - con_current->selstartline = NULL; - con_current->selendline = NULL; + 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); diff --git a/engine/client/keys.c b/engine/client/keys.c index f9d95365f..ad33e341f 100644 --- a/engine/client/keys.c +++ b/engine/client/keys.c @@ -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; - con->userline = con->selstartline; - con->useroffset = con->selstartoffset; + 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 (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); - /* - char *clipText = Sys_GetClipboard(); - if (clipText) - { - Key_EntryInsert(line, linepos, clipText); - Sys_CloseClipboard(clipText); - } - */ 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; - con->buttonsdown = CB_SCROLL; + 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); } //============================================================================ diff --git a/engine/client/sys_win.c b/engine/client/sys_win.c index 313b3e402..95127b8b9 100644 --- a/engine/client/sys_win.c +++ b/engine/client/sys_win.c @@ -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); } diff --git a/engine/common/cmd.c b/engine/common/cmd.c index 566fe9901..c7fe1d146 100644 --- a/engine/common/cmd.c +++ b/engine/common/cmd.c @@ -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)); } /* diff --git a/engine/common/cmd.h b/engine/common/cmd.h index 8fef7576b..4d086b1bb 100644 --- a/engine/common/cmd.h +++ b/engine/common/cmd.h @@ -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 \ No newline at end of file diff --git a/engine/common/common.c b/engine/common/common.c index 5ad29a529..e1f2dd80c 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -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 diff --git a/engine/common/console.h b/engine/common/console.h index 280a8890a..8b92f423c 100644 --- a/engine/common/console.h +++ b/engine/common/console.h @@ -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; diff --git a/engine/common/fs.c b/engine/common/fs.c index 78438f638..5235362c5 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -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); diff --git a/engine/common/pr_bgcmd.c b/engine/common/pr_bgcmd.c index 7bb7706e8..3c65cc542 100644 --- a/engine/common/pr_bgcmd.c +++ b/engine/common/pr_bgcmd.c @@ -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,43 +4611,74 @@ 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; - - func = PR_FindFunction(prinst, "URI_Get_Callback", PR_ANY); - if (!func) - Con_Printf("URI_Get_Callback missing\n"); - else if (func) + //make sure the progs vm is still active and okay. + if (prinst && ctx->spawncount == w->spawncount) { - int len; - char *buffer; - struct globalvars_s *pr_globals = PR_globals(prinst, PR_CURRENT); - - *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_INT(OFS_PARM2) = 0; - - if (dl->file) + func = PR_FindFunction(prinst, "URI_Get_Callback", PR_ANY); + if (!func) + Con_Printf("URI_Get_Callback missing\n"); + else if (func) { - len = VFS_GETLEN(dl->file); - buffer = malloc(len+1); - buffer[len] = 0; - VFS_READ(dl->file, buffer, len); - G_INT(OFS_PARM2) = PR_TempString(prinst, buffer); - free(buffer); - } + 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) = (replycode!=200)?replycode:0; //for compat with DP, we change any 200s to 0. + G_INT(OFS_PARM2) = 0; - PR_ExecuteProgram(prinst, func); + if (ctx->file) + { + len = VFS_GETLEN(ctx->file); + buffer = malloc(len+1); + buffer[len] = 0; + 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 diff --git a/engine/common/q1bsp.c b/engine/common/q1bsp.c index f76fcc8ff..6737f9af1 100644 --- a/engine/common/q1bsp.c +++ b/engine/common/q1bsp.c @@ -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++) diff --git a/engine/gl/gl_font.c b/engine/gl/gl_font.c index cc44d7f51..4018750ee 100644 --- a/engine/gl/gl_font.c +++ b/engine/gl/gl_font.c @@ -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)); diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index 0d2884250..d7bef6246 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -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) { diff --git a/engine/gl/gl_vidlinuxglx.c b/engine/gl/gl_vidlinuxglx.c index e3cc280fc..b81fd9b3e 100644 --- a/engine/gl/gl_vidlinuxglx.c +++ b/engine/gl/gl_vidlinuxglx.c @@ -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,18 +2565,18 @@ 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)) { - int uc =utf8_decode(&err, in, &in); + int uc = utf8_decode(&err, in, &in); if ((uc >= 0xe000 && uc <= 0xe100) && (uc&0x7f) >= 32) uc = uc&0x7f; //don't do c0/c1 glyphs. otherwise treat as ascii. else if (uc > 255 || err) @@ -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. - xa_clipboard = x11.pXInternAtom(vid_dpy, "CLIPBOARD", false); + 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); } } diff --git a/engine/server/world.c b/engine/server/world.c index c82a8e4d7..9ed97c3ee 100644 --- a/engine/server/world.c +++ b/engine/server/world.c @@ -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