summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon TURNEY <jon.turney@dronecode.org.uk>2014-11-11 12:11:16 +0000
committerJon TURNEY <jon.turney@dronecode.org.uk>2014-11-11 12:11:16 +0000
commit55670e770b0c8ac5290ee4c97325d881bb1fab02 (patch)
tree75c21f6809d5e2068a4cd7991d8f799f3feef188
parente65ada62cafc90caa23bcbf8240c66eaceb318fc (diff)
parent7ec7ac8d1db031262e102cdb9345779a32025dcc (diff)
Merge branch 'cygwin-patches-for-1.16' into cygwin-release-1.16xserver-cygwin-1.16.2-1
-rw-r--r--hw/xwin/InitOutput.c14
-rw-r--r--hw/xwin/man/XWin.man3
-rw-r--r--hw/xwin/win.h3
-rw-r--r--hw/xwin/winclipboard/internal.h8
-rw-r--r--hw/xwin/winclipboard/thread.c9
-rw-r--r--hw/xwin/winclipboard/wndproc.c114
-rw-r--r--hw/xwin/winclipboard/xevents.c36
-rw-r--r--hw/xwin/wincreatewnd.c6
-rw-r--r--hw/xwin/winmultiwindowwm.c32
-rw-r--r--hw/xwin/winprocarg.c6
-rw-r--r--hw/xwin/winvalargs.c2
-rw-r--r--hw/xwin/winwndproc.c2
-rw-r--r--os/log.c28
-rw-r--r--os/xdmcp.c7
14 files changed, 207 insertions, 63 deletions
diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c
index a7773c5b8..111b3a8f2 100644
--- a/hw/xwin/InitOutput.c
+++ b/hw/xwin/InitOutput.c
@@ -716,6 +716,20 @@ OsVendorInit(void)
}
}
}
+
+ /* Work out what the default resize setting should be, and apply it if it
+ was not explicitly specified */
+ {
+ int j;
+ for (j = 0; j < g_iNumScreens; j++) {
+ if (g_ScreenInfo[j].iResizeMode == resizeDefault) {
+ if (g_ScreenInfo[j].fFullScreen)
+ g_ScreenInfo[j].iResizeMode = resizeNotAllowed;
+ else
+ g_ScreenInfo[j].iResizeMode = resizeWithRandr;
+ }
+ }
+ }
}
static void
diff --git a/hw/xwin/man/XWin.man b/hw/xwin/man/XWin.man
index 5f2d2eabc..3d59f9b8e 100644
--- a/hw/xwin/man/XWin.man
+++ b/hw/xwin/man/XWin.man
@@ -124,7 +124,8 @@ Alternative name for \fB\-resize=scrollbars\fP.
.SH OPTIONS CONTROLLING RESIZE BEHAVIOUR
.TP 8
.B \-resize[=none|scrollbars|randr]
-Select the resize mode of an X screen. The default is randr.
+Select the resize mode of an X screen.
+The default is \fBnone\fP if \fB\-fullscreen\fP is used, \fBrandr\fP otherwise.
.RS
.IP \fB\-resize=none\fP 8
diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index 5c1ce32f1..c18c791f9 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -361,7 +361,8 @@ typedef struct {
* Resize modes
*/
typedef enum {
- notAllowed,
+ resizeDefault = -1,
+ resizeNotAllowed,
resizeWithScrollbars,
resizeWithRandr
} winResizeMode;
diff --git a/hw/xwin/winclipboard/internal.h b/hw/xwin/winclipboard/internal.h
index c6bde84af..33203612e 100644
--- a/hw/xwin/winclipboard/internal.h
+++ b/hw/xwin/winclipboard/internal.h
@@ -77,6 +77,14 @@ typedef struct
Atom atomTargets;
} ClipboardAtoms;
+/* Modern clipboard API functions */
+typedef wBOOL WINAPI (*ADDCLIPBOARDFORMATLISTENERPROC)(HWND hwnd);
+typedef wBOOL WINAPI (*REMOVECLIPBOARDFORMATLISTENERPROC)(HWND hwnd);
+
+extern Bool g_fHasModernClipboardApi;
+extern ADDCLIPBOARDFORMATLISTENERPROC g_fpAddClipboardFormatListener;
+extern REMOVECLIPBOARDFORMATLISTENERPROC g_fpRemoveClipboardFormatListener;
+
/*
* winclipboardwndproc.c
*/
diff --git a/hw/xwin/winclipboard/thread.c b/hw/xwin/winclipboard/thread.c
index 88af88f78..f6a4868c7 100644
--- a/hw/xwin/winclipboard/thread.c
+++ b/hw/xwin/winclipboard/thread.c
@@ -84,6 +84,10 @@ static pthread_t g_winClipboardProcThread;
int xfixes_event_base;
int xfixes_error_base;
+Bool g_fHasModernClipboardApi = FALSE;
+ADDCLIPBOARDFORMATLISTENERPROC g_fpAddClipboardFormatListener;
+REMOVECLIPBOARDFORMATLISTENERPROC g_fpRemoveClipboardFormatListener;
+
/*
* Local function prototypes
*/
@@ -125,6 +129,11 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
winDebug("winClipboardProc - Hello\n");
+ g_fpAddClipboardFormatListener = (ADDCLIPBOARDFORMATLISTENERPROC)GetProcAddress(GetModuleHandle("user32"),"AddClipboardFormatListener");
+ g_fpRemoveClipboardFormatListener = (REMOVECLIPBOARDFORMATLISTENERPROC)GetProcAddress(GetModuleHandle("user32"),"RemoveClipboardFormatListener");
+ g_fHasModernClipboardApi = g_fpAddClipboardFormatListener && g_fpRemoveClipboardFormatListener;
+ ErrorF("OS maintains clipboard viewer chain: %s\n", g_fHasModernClipboardApi ? "yes" : "no");
+
/* Set error handler */
static Bool fErrorHandlerSet = FALSE;
diff --git a/hw/xwin/winclipboard/wndproc.c b/hw/xwin/winclipboard/wndproc.c
index dd30b8c99..c94096a76 100644
--- a/hw/xwin/winclipboard/wndproc.c
+++ b/hw/xwin/winclipboard/wndproc.c
@@ -58,6 +58,9 @@
#define WIN_POLL_TIMEOUT 1
+#ifndef WM_CLIPBOARDUPDATE
+#define WM_CLIPBOARDUPDATE 0x031D
+#endif
/*
* Process X events up to specified timeout
@@ -151,8 +154,16 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
winDebug("winClipboardWindowProc - WM_DESTROY\n");
- /* Remove ourselves from the clipboard chain */
- ChangeClipboardChain(hwnd, s_hwndNextViewer);
+ if (g_fHasModernClipboardApi)
+ {
+ /* Remove clipboard listener */
+ g_fpRemoveClipboardFormatListener(hwnd);
+ }
+ else
+ {
+ /* Remove ourselves from the clipboard chain */
+ ChangeClipboardChain(hwnd, s_hwndNextViewer);
+ }
s_hwndNextViewer = NULL;
}
@@ -168,9 +179,6 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
case WM_CREATE:
{
- HWND first, next;
- DWORD error_code = 0;
-
winDebug("winClipboardWindowProc - WM_CREATE\n");
ClipboardWindowCreationParams *cwcp = (ClipboardWindowCreationParams *)((CREATESTRUCT *)lParam)->lpCreateParams;
@@ -179,16 +187,26 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
atoms = cwcp->atoms;
fRunning = TRUE;
- first = GetClipboardViewer(); /* Get handle to first viewer in chain. */
- if (first == hwnd)
- return 0; /* Make sure it's not us! */
- /* Add ourselves to the clipboard viewer chain */
- next = SetClipboardViewer(hwnd);
- error_code = GetLastError();
- if (SUCCEEDED(error_code) && (next == first)) /* SetClipboardViewer must have succeeded, and the handle */
- s_hwndNextViewer = next; /* it returned must have been the first window in the chain */
+ if (g_fHasModernClipboardApi)
+ {
+ g_fpAddClipboardFormatListener(hwnd);
+ }
else
- s_fCBCInitialized = FALSE;
+ {
+ HWND first, next;
+ DWORD error_code = 0;
+
+ first = GetClipboardViewer(); /* Get handle to first viewer in chain. */
+ if (first == hwnd)
+ return 0; /* Make sure it's not us! */
+ /* Add ourselves to the clipboard viewer chain */
+ next = SetClipboardViewer(hwnd);
+ error_code = GetLastError();
+ if (SUCCEEDED(error_code) && (next == first)) /* SetClipboardViewer must have succeeded, and the handle */
+ s_hwndNextViewer = next; /* it returned must have been the first window in the chain */
+ else
+ s_fCBCInitialized = FALSE;
+ }
}
return 0;
@@ -233,6 +251,11 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
winDebug("winClipboardWindowProc - WM_WM_REINIT: Enter\n");
+ if (g_fHasModernClipboardApi)
+ {
+ return 0;
+ }
+
first = GetClipboardViewer(); /* Get handle to first viewer in chain. */
if (first == hwnd)
return 0; /* Make sure it's not us! */
@@ -257,38 +280,45 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
return 0;
case WM_DRAWCLIPBOARD:
+ case WM_CLIPBOARDUPDATE:
{
static Bool s_fProcessingDrawClipboard = FALSE;
int iReturn;
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Enter\n");
-
- /*
- * We've occasionally seen a loop in the clipboard chain.
- * Try and fix it on the first hint of recursion.
- */
- if (!s_fProcessingDrawClipboard) {
- s_fProcessingDrawClipboard = TRUE;
- }
- else {
- /* Attempt to break the nesting by getting out of the chain, twice?, and then fix and bail */
- s_fCBCInitialized = FALSE;
- ChangeClipboardChain(hwnd, s_hwndNextViewer);
- winFixClipboardChain();
- ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
- "Nested calls detected. Re-initing.\n");
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
- s_fProcessingDrawClipboard = FALSE;
- return 0;
- }
-
- /* Bail on first message */
- if (!s_fCBCInitialized) {
- s_fCBCInitialized = TRUE;
- s_fProcessingDrawClipboard = FALSE;
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
- return 0;
- }
+ if (message == WM_DRAWCLIPBOARD)
+ winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Enter\n");
+ else
+ winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE: Enter\n");
+
+ if (!g_fHasModernClipboardApi)
+ {
+ /*
+ * We've occasionally seen a loop in the clipboard chain.
+ * Try and fix it on the first hint of recursion.
+ */
+ if (!s_fProcessingDrawClipboard) {
+ s_fProcessingDrawClipboard = TRUE;
+ }
+ else {
+ /* Attempt to break the nesting by getting out of the chain, twice?, and then fix and bail */
+ s_fCBCInitialized = FALSE;
+ ChangeClipboardChain(hwnd, s_hwndNextViewer);
+ winFixClipboardChain();
+ ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ "Nested calls detected. Re-initing.\n");
+ winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
+ s_fProcessingDrawClipboard = FALSE;
+ return 0;
+ }
+
+ /* Bail on first message */
+ if (!s_fCBCInitialized) {
+ s_fCBCInitialized = TRUE;
+ s_fProcessingDrawClipboard = FALSE;
+ winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
+ return 0;
+ }
+ }
/*
* NOTE: We cannot bail out when NULL == GetClipboardOwner ()
diff --git a/hw/xwin/winclipboard/xevents.c b/hw/xwin/winclipboard/xevents.c
index 8135b1cde..16c8b2a0b 100644
--- a/hw/xwin/winclipboard/xevents.c
+++ b/hw/xwin/winclipboard/xevents.c
@@ -78,6 +78,18 @@ static const char *szSelectionNames[CLIP_NUM_SELECTIONS] =
static unsigned int lastOwnedSelectionIndex = CLIP_OWN_NONE;
+static const char *
+GetWindowName(HWND hWnd)
+{
+ static char *pBuf = NULL;
+ int len = GetWindowTextLength(hWnd);
+ len++;
+ pBuf = realloc(pBuf, len + 1);
+ GetWindowText(hWnd, pBuf, len);
+ pBuf[len] = 0;
+ return pBuf;
+}
+
static void
MonitorSelection(XFixesSelectionNotifyEvent * e, unsigned int i)
{
@@ -313,7 +325,7 @@ winClipboardFlushXEvents(HWND hwnd,
/* Access the clipboard */
if (!OpenClipboard(hwnd)) {
ErrorF("winClipboardFlushXEvents - SelectionRequest - "
- "OpenClipboard () failed: %08lx owner %08x\n", GetLastError(), GetClipboardOwner());
+ "OpenClipboard () failed: %08lx owner %08x\n", GetLastError(), GetClipboardOwner(), GetWindowName(GetClipboardOwner()));
/* Abort */
fAbort = TRUE;
@@ -375,6 +387,26 @@ winClipboardFlushXEvents(HWND hwnd,
ErrorF("winClipboardFlushXEvents - SelectionRequest - "
"GetClipboardData () failed: %08lx\n", GetLastError());
+ unsigned int format = 0;
+
+ do {
+ format = EnumClipboardFormats(format);
+ if (GetLastError() != ERROR_SUCCESS) {
+ winDebug
+ ("winClipboardFlushXEvents - SelectionRequest - EnumClipboardFormats failed %x\n",
+ GetLastError());
+ }
+ if (format > 0xc000) {
+ char buff[256];
+
+ GetClipboardFormatName(format, buff, 256);
+ winDebug("winClipboardFlushXEvents - SelectionRequest - %d %s\n", format,
+ buff);
+ }
+ else if (format > 0)
+ winDebug("winClipboardFlushXEvents - SelectionRequest - %d\n", format);
+ } while (format != 0);
+
/* Abort */
fAbort = TRUE;
goto winClipboardFlushXEvents_SelectionRequest_Done;
@@ -845,7 +877,7 @@ winClipboardFlushXEvents(HWND hwnd,
/* Access the Windows clipboard */
if (!OpenClipboard(hwnd)) {
ErrorF("winClipboardFlushXEvents - OpenClipboard () failed: %08x Owner %08x\n",
- (int) GetLastError(), GetClipboardOwner());
+ (int) GetLastError(), GetClipboardOwner(), GetWindowName(GetClipboardOwner()));
break;
}
diff --git a/hw/xwin/wincreatewnd.c b/hw/xwin/wincreatewnd.c
index 6732dcb58..8ce646181 100644
--- a/hw/xwin/wincreatewnd.c
+++ b/hw/xwin/wincreatewnd.c
@@ -183,7 +183,7 @@ winCreateBoundingWindowWindowed(ScreenPtr pScreen)
fForceShowWindow = TRUE;
}
dwWindowStyle |= WS_CAPTION;
- if (pScreenInfo->iResizeMode != notAllowed)
+ if (pScreenInfo->iResizeMode != resizeNotAllowed)
dwWindowStyle |= WS_THICKFRAME | WS_MAXIMIZEBOX;
}
else
@@ -238,7 +238,7 @@ winCreateBoundingWindowWindowed(ScreenPtr pScreen)
)
&& (pScreenInfo->iResizeMode == resizeWithScrollbars)) {
/* We cannot have scrollbars if we do not have a window border */
- pScreenInfo->iResizeMode = notAllowed;
+ pScreenInfo->iResizeMode = resizeNotAllowed;
}
/* Did the user specify a height and width? */
@@ -265,7 +265,7 @@ winCreateBoundingWindowWindowed(ScreenPtr pScreen)
#endif
/* Are we resizable */
- if (pScreenInfo->iResizeMode != notAllowed) {
+ if (pScreenInfo->iResizeMode != resizeNotAllowed) {
#if CYGDEBUG
winDebug
("winCreateBoundingWindowWindowed - Window is resizable\n");
diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index 9bee66953..e281fad31 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -130,11 +130,15 @@ typedef struct _WMMsgQueueRec {
typedef struct _WMInfo {
Display *pDisplay;
WMMsgQueueRec wmMsgQueue;
+ Atom atmUTF8String;
Atom atmWmProtos;
Atom atmWmDelete;
Atom atmWmTakeFocus;
Atom atmPrivMap;
Atom atmNetWmName;
+ Atom atmCurrentDesktop;
+ Atom atmNumberDesktops;
+ Atom atmDesktopNames;
Bool fAllowOtherWM;
} WMInfoRec, *WMInfoPtr;
@@ -1437,6 +1441,8 @@ winInitMultiWindowWM(WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
int iRetries = 0;
char pszDisplay[512];
int iReturn;
+ int data;
+ const char buf[] = "Desktop";
winDebug("winInitMultiWindowWM - Hello\n");
@@ -1520,6 +1526,8 @@ winInitMultiWindowWM(WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
"successfully opened the display.\n");
/* Create some atoms */
+ pWMInfo->atmUTF8String = XInternAtom(pWMInfo->pDisplay,
+ "UTF8_STRING", False);
pWMInfo->atmWmProtos = XInternAtom(pWMInfo->pDisplay,
"WM_PROTOCOLS", False);
pWMInfo->atmWmDelete = XInternAtom(pWMInfo->pDisplay,
@@ -1530,6 +1538,30 @@ winInitMultiWindowWM(WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
WINDOWSWM_NATIVE_HWND, False);
pWMInfo->atmNetWmName = XInternAtom(pWMInfo->pDisplay,
"_NET_WM_NAME", False);
+ pWMInfo->atmCurrentDesktop = XInternAtom(pWMInfo->pDisplay,
+ "_NET_CURRENT_DESKTOP", False);
+ pWMInfo->atmNumberDesktops = XInternAtom(pWMInfo->pDisplay,
+ "_NET_NUMBER_OF_DESKTOPS", False);
+ pWMInfo->atmDesktopNames = XInternAtom(pWMInfo->pDisplay,
+ "_NET_DESKTOP_NAMES", False);
+
+ /*
+ Set root window properties for describing multiple desktops to describe
+ the one desktop we have
+ */
+ data = 0;
+ XChangeProperty(pWMInfo->pDisplay, XDefaultRootWindow(pWMInfo->pDisplay),
+ pWMInfo->atmCurrentDesktop, XA_CARDINAL, 32,
+ PropModeReplace, (unsigned char *) &data, 1);
+
+ data = 1;
+ XChangeProperty(pWMInfo->pDisplay, XDefaultRootWindow(pWMInfo->pDisplay),
+ pWMInfo->atmNumberDesktops, XA_CARDINAL, 32,
+ PropModeReplace, (unsigned char *) &data, 1);
+
+ XChangeProperty(pWMInfo->pDisplay, XDefaultRootWindow(pWMInfo->pDisplay),
+ pWMInfo->atmDesktopNames, pWMInfo->atmUTF8String, 8,
+ PropModeReplace, (unsigned char *) buf, strlen(buf));
if (1) {
Cursor cursor = XCreateFontCursor(pWMInfo->pDisplay, XC_left_ptr);
diff --git a/hw/xwin/winprocarg.c b/hw/xwin/winprocarg.c
index 0a8337482..2c451ecbd 100644
--- a/hw/xwin/winprocarg.c
+++ b/hw/xwin/winprocarg.c
@@ -147,7 +147,7 @@ winInitializeScreenDefaults(void)
#endif
defaultScreenInfo.fMultipleMonitors = FALSE;
defaultScreenInfo.fLessPointer = FALSE;
- defaultScreenInfo.iResizeMode = resizeWithRandr;
+ defaultScreenInfo.iResizeMode = resizeDefault;
defaultScreenInfo.fNoTrayIcon = FALSE;
defaultScreenInfo.iE3BTimeout = WIN_E3B_DEFAULT;
defaultScreenInfo.fUseWinKillKey = WIN_DEFAULT_WIN_KILL;
@@ -672,7 +672,7 @@ ddxProcessArgument(int argc, char *argv[], int i)
if (IS_OPTION("-resize"))
mode = resizeWithRandr;
else if (IS_OPTION("-noresize"))
- mode = notAllowed;
+ mode = resizeNotAllowed;
else if (strncmp(argv[i], "-resize=", strlen("-resize=")) == 0) {
char *option = argv[i] + strlen("-resize=");
@@ -681,7 +681,7 @@ ddxProcessArgument(int argc, char *argv[], int i)
else if (strcmp(option, "scrollbars") == 0)
mode = resizeWithScrollbars;
else if (strcmp(option, "none") == 0)
- mode = notAllowed;
+ mode = resizeNotAllowed;
else {
ErrorF("ddxProcessArgument - resize - Invalid resize mode %s\n",
option);
diff --git a/hw/xwin/winvalargs.c b/hw/xwin/winvalargs.c
index edfd71f72..d0e0b7519 100644
--- a/hw/xwin/winvalargs.c
+++ b/hw/xwin/winvalargs.c
@@ -153,7 +153,7 @@ winValidateArgs(void)
/* Check for fullscreen and any non-fullscreen parameters */
if (g_ScreenInfo[i].fFullScreen
- && ((g_ScreenInfo[i].iResizeMode != notAllowed)
+ && ((g_ScreenInfo[i].iResizeMode != resizeNotAllowed)
|| !g_ScreenInfo[i].fDecoration
|| g_ScreenInfo[i].fLessPointer)) {
ErrorF("winValidateArgs - -fullscreen is invalid with "
diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c
index ccea2aa77..1600efe05 100644
--- a/hw/xwin/winwndproc.c
+++ b/hw/xwin/winwndproc.c
@@ -334,7 +334,7 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
#endif
/* Break if we do not allow resizing */
- if ((s_pScreenInfo->iResizeMode == notAllowed)
+ if ((s_pScreenInfo->iResizeMode == resizeNotAllowed)
|| !s_pScreenInfo->fDecoration
#ifdef XWIN_MULTIWINDOWEXTWM
|| s_pScreenInfo->fMWExtWM
diff --git a/os/log.c b/os/log.c
index 9df8aa7e0..241583a95 100644
--- a/os/log.c
+++ b/os/log.c
@@ -354,6 +354,7 @@ vpnprintf(char *string, int size_in, const char *f, va_list args)
uint64_t ui;
int64_t si;
size_t size = size_in;
+ int precision;
for (; f_idx < f_len && s_idx < size - 1; f_idx++) {
int length_modifier = 0;
@@ -364,9 +365,29 @@ vpnprintf(char *string, int size_in, const char *f, va_list args)
f_idx++;
- /* silently swallow digit length modifiers */
- while (f_idx < f_len && ((f[f_idx] >= '0' && f[f_idx] <= '9') || f[f_idx] == '.'))
+ /* silently swallow minimum field width */
+ if (f[f_idx] == '*') {
f_idx++;
+ va_arg(args, int);
+ } else {
+ while (f_idx < f_len && ((f[f_idx] >= '0' && f[f_idx] <= '9')))
+ f_idx++;
+ }
+
+ /* is there a precision? */
+ precision = size;
+ if (f[f_idx] == '.') {
+ f_idx++;
+ if (f[f_idx] == '*') {
+ f_idx++;
+ /* precision is supplied in an int argument */
+ precision = va_arg(args, int);
+ } else {
+ /* silently swallow precision digits */
+ while (f_idx < f_len && ((f[f_idx] >= '0' && f[f_idx] <= '9')))
+ f_idx++;
+ }
+ }
/* non-digit length modifiers */
if (f_idx < f_len) {
@@ -382,9 +403,8 @@ vpnprintf(char *string, int size_in, const char *f, va_list args)
switch (f[f_idx]) {
case 's':
string_arg = va_arg(args, char*);
- p_len = strlen_sigsafe(string_arg);
- for (i = 0; i < p_len && s_idx < size - 1; i++)
+ for (i = 0; string_arg[i] != 0 && s_idx < size - 1 && s_idx < precision; i++)
string[s_idx++] = string_arg[i];
break;
diff --git a/os/xdmcp.c b/os/xdmcp.c
index c5204adfb..99616d94b 100644
--- a/os/xdmcp.c
+++ b/os/xdmcp.c
@@ -1409,11 +1409,8 @@ recv_alive_msg(unsigned length)
static void
XdmcpFatal(const char *type, ARRAY8Ptr status)
{
- char *text = malloc(status->length + 1);
- strncpy(text, status->data, status->length);
- text[status->length] = 0;
- FatalError("XDMCP fatal error: %s %s\n", type, text);
- free(text);
+ FatalError("XDMCP fatal error: %s %*.*s\n", type,
+ status->length, status->length, status->data);
}
static void