X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=windows%2Fwinctrls.c;h=a03967e6f81917a07e9669ea89448ba9b57098d7;hb=510f49e405e71ba5c97875e7a019364e1ef5fac9;hp=0fb4b9fcc012410ad89fe729fbaa25e26b5e79b0;hpb=cb45b9cc253d6f661b2d90003b699c1558ca2bf4;p=PuTTY.git diff --git a/windows/winctrls.c b/windows/winctrls.c index 0fb4b9fc..a03967e6 100644 --- a/windows/winctrls.c +++ b/windows/winctrls.c @@ -76,7 +76,7 @@ HWND doctl(struct ctlpos *cp, RECT r, if (cp->hwnd) { ctl = CreateWindowEx(exstyle, wclass, wtext, wstyle, r.left, r.top, r.right, r.bottom, - cp->hwnd, (HMENU) wid, hinst, NULL); + cp->hwnd, (HMENU)(ULONG_PTR)wid, hinst, NULL); SendMessage(ctl, WM_SETFONT, cp->font, MAKELPARAM(TRUE, 0)); if (!strcmp(wclass, "LISTBOX")) { @@ -148,44 +148,29 @@ void endbox(struct ctlpos *cp) } /* - * Some edit boxes. Each one has a static above it. The percentages - * of the horizontal space are provided. + * A static line, followed by a full-width edit box. */ -void multiedit(struct ctlpos *cp, int password, ...) +void editboxfw(struct ctlpos *cp, int password, char *text, + int staticid, int editid) { RECT r; - va_list ap; - int percent, xpos; - - percent = xpos = 0; - va_start(ap, password); - while (1) { - char *text; - int staticid, editid, pcwidth; - text = va_arg(ap, char *); - if (!text) - break; - staticid = va_arg(ap, int); - editid = va_arg(ap, int); - pcwidth = va_arg(ap, int); - r.left = xpos + GAPBETWEEN; - percent += pcwidth; - xpos = (cp->width + GAPBETWEEN) * percent / 100; - r.right = xpos - r.left; + r.left = GAPBETWEEN; + r.right = cp->width; + if (text) { r.top = cp->ypos; r.bottom = STATICHEIGHT; doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, text, staticid); - r.top = cp->ypos + 8 + GAPWITHIN; - r.bottom = EDITHEIGHT; - doctl(cp, r, "EDIT", - WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL | - (password ? ES_PASSWORD : 0), - WS_EX_CLIENTEDGE, "", editid); + cp->ypos += STATICHEIGHT + GAPWITHIN; } - va_end(ap); - cp->ypos += STATICHEIGHT + GAPWITHIN + EDITHEIGHT + GAPBETWEEN; + r.top = cp->ypos; + r.bottom = EDITHEIGHT; + doctl(cp, r, "EDIT", + WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL | + (password ? ES_PASSWORD : 0), + WS_EX_CLIENTEDGE, "", editid); + cp->ypos += EDITHEIGHT + GAPBETWEEN; } /* @@ -198,16 +183,18 @@ void combobox(struct ctlpos *cp, char *text, int staticid, int listid) r.left = GAPBETWEEN; r.right = cp->width; + if (text) { + r.top = cp->ypos; + r.bottom = STATICHEIGHT; + doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, text, staticid); + cp->ypos += STATICHEIGHT + GAPWITHIN; + } r.top = cp->ypos; - r.bottom = STATICHEIGHT; - doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, text, staticid); - r.top = cp->ypos + 8 + GAPWITHIN; r.bottom = COMBOHEIGHT * 10; doctl(cp, r, "COMBOBOX", WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWN | CBS_HASSTRINGS, WS_EX_CLIENTEDGE, "", listid); - - cp->ypos += STATICHEIGHT + GAPWITHIN + COMBOHEIGHT + GAPBETWEEN; + cp->ypos += COMBOHEIGHT + GAPBETWEEN; } struct radio { char *text; int id; }; @@ -280,10 +267,9 @@ void radioline(struct ctlpos *cp, char *text, int id, int nacross, ...) nbuttons = 0; while (1) { char *btext = va_arg(ap, char *); - int bid; if (!btext) break; - bid = va_arg(ap, int); + (void) va_arg(ap, int); /* id */ nbuttons++; } va_end(ap); @@ -312,10 +298,10 @@ void bareradioline(struct ctlpos *cp, int nacross, ...) nbuttons = 0; while (1) { char *btext = va_arg(ap, char *); - int bid; if (!btext) break; - bid = va_arg(ap, int); + (void) va_arg(ap, int); /* id */ + nbuttons++; } va_end(ap); buttons = snewn(nbuttons, struct radio); @@ -343,10 +329,10 @@ void radiobig(struct ctlpos *cp, char *text, int id, ...) nbuttons = 0; while (1) { char *btext = va_arg(ap, char *); - int bid; if (!btext) break; - bid = va_arg(ap, int); + (void) va_arg(ap, int); /* id */ + nbuttons++; } va_end(ap); buttons = snewn(nbuttons, struct radio); @@ -385,7 +371,6 @@ void checkbox(struct ctlpos *cp, char *text, int id) char *staticwrap(struct ctlpos *cp, HWND hwnd, char *text, int *lines) { HDC hdc = GetDC(hwnd); - int lpx = GetDeviceCaps(hdc, LOGPIXELSX); int width, nlines, j; INT *pwidths, nfit; SIZE size; @@ -461,6 +446,8 @@ char *staticwrap(struct ctlpos *cp, HWND hwnd, char *text, int *lines) if (lines) *lines = nlines; + sfree(pwidths); + return ret; } @@ -670,7 +657,7 @@ void staticddl(struct ctlpos *cp, char *stext, r.right = rwid; r.bottom = COMBOHEIGHT*4; doctl(cp, r, "COMBOBOX", - WS_CHILD | WS_VISIBLE | WS_TABSTOP | + WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_CLIENTEDGE, "", lid); cp->ypos += height + GAPBETWEEN; @@ -717,19 +704,21 @@ void staticddlbig(struct ctlpos *cp, char *stext, { RECT r; - r.left = GAPBETWEEN; - r.top = cp->ypos; - r.right = cp->width; - r.bottom = STATICHEIGHT; - doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid); - cp->ypos += STATICHEIGHT; + if (stext) { + r.left = GAPBETWEEN; + r.top = cp->ypos; + r.right = cp->width; + r.bottom = STATICHEIGHT; + doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid); + cp->ypos += STATICHEIGHT; + } r.left = GAPBETWEEN; r.top = cp->ypos; r.right = cp->width; r.bottom = COMBOHEIGHT*4; doctl(cp, r, "COMBOBOX", - WS_CHILD | WS_VISIBLE | WS_TABSTOP | + WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_CLIENTEDGE, "", lid); cp->ypos += COMBOHEIGHT + GAPBETWEEN; } @@ -742,12 +731,14 @@ void bigeditctrl(struct ctlpos *cp, char *stext, { RECT r; - r.left = GAPBETWEEN; - r.top = cp->ypos; - r.right = cp->width; - r.bottom = STATICHEIGHT; - cp->ypos += r.bottom + GAPWITHIN; - doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid); + if (stext) { + r.left = GAPBETWEEN; + r.top = cp->ypos; + r.right = cp->width; + r.bottom = STATICHEIGHT; + cp->ypos += r.bottom + GAPWITHIN; + doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid); + } r.left = GAPBETWEEN; r.top = cp->ypos; @@ -1048,6 +1039,10 @@ int handle_prefslist(struct prefslist *hdl, int dest = 0; /* initialise to placate gcc */ switch (dlm->uNotification) { case DL_BEGINDRAG: + /* Add a dummy item to make pl_itemfrompt() work + * better. + * FIXME: this causes scrollbar glitches if the count of + * listbox contains >= its height. */ hdl->dummyitem = SendDlgItemMessage(hwnd, hdl->listid, LB_ADDSTRING, 0, (LPARAM) ""); @@ -1055,7 +1050,7 @@ int handle_prefslist(struct prefslist *hdl, hdl->srcitem = LBItemFromPt(dlm->hWnd, dlm->ptCursor, TRUE); hdl->dragging = 0; /* XXX hack Q183115 */ - SetWindowLong(hwnd, DWL_MSGRESULT, TRUE); + SetWindowLongPtr(hwnd, DWLP_MSGRESULT, TRUE); ret |= 1; break; case DL_CANCELDRAG: DrawInsert(hwnd, dlm->hWnd, -1); /* Clear arrow */ @@ -1069,9 +1064,9 @@ int handle_prefslist(struct prefslist *hdl, if (dest > hdl->dummyitem) dest = hdl->dummyitem; DrawInsert (hwnd, dlm->hWnd, dest); if (dest >= 0) - SetWindowLong(hwnd, DWL_MSGRESULT, DL_MOVECURSOR); + SetWindowLongPtr(hwnd, DWLP_MSGRESULT, DL_MOVECURSOR); else - SetWindowLong(hwnd, DWL_MSGRESULT, DL_STOPCURSOR); + SetWindowLongPtr(hwnd, DWLP_MSGRESULT, DL_STOPCURSOR); ret |= 1; break; case DL_DROPPED: if (hdl->dragging) { @@ -1166,10 +1161,11 @@ void progressbar(struct ctlpos *cp, int id) * Return value is a malloc'ed copy of the processed version of the * string. */ -static char *shortcut_escape(char *text, char shortcut) +static char *shortcut_escape(const char *text, char shortcut) { char *ret; - char *p, *q; + char const *p; + char *q; if (!text) return NULL; /* sfree won't choke on this */ @@ -1508,8 +1504,8 @@ void winctrl_layout(struct dlgparam *dp, struct winctrls *wc, combobox(&pos, escaped, base_id, base_id+1); else - multiedit(&pos, ctrl->editbox.password, escaped, - base_id, base_id+1, 100, NULL); + editboxfw(&pos, ctrl->editbox.password, escaped, + base_id, base_id+1); } else { if (ctrl->editbox.has_list) { staticcombo(&pos, escaped, base_id, base_id+1, @@ -1643,8 +1639,8 @@ void winctrl_layout(struct dlgparam *dp, struct winctrls *wc, shortcuts[nshortcuts++] = ctrl->fontselect.shortcut; statictext(&pos, escaped, 1, base_id); staticbtn(&pos, "", base_id+1, "Change...", base_id+2); + data = fontspec_new("", 0, 0, 0); sfree(escaped); - data = snew(FontSpec); break; default: assert(!"Can't happen"); @@ -1669,7 +1665,9 @@ void winctrl_layout(struct dlgparam *dp, struct winctrls *wc, winctrl_add_shortcuts(dp, c); if (actual_base_id == base_id) base_id += num_ids; - } + } else { + sfree(data); + } if (colstart >= 0) { /* @@ -1905,14 +1903,8 @@ int winctrl_handle_command(struct dlgparam *dp, UINT msg, HIWORD(wParam) == BN_DOUBLECLICKED))) { OPENFILENAME of; char filename[FILENAME_MAX]; - int ret; memset(&of, 0, sizeof(of)); -#ifdef OPENFILENAME_SIZE_VERSION_400 - of.lStructSize = OPENFILENAME_SIZE_VERSION_400; -#else - of.lStructSize = sizeof(of); -#endif of.hwndOwner = dp->hwnd; if (ctrl->fileselect.filter) of.lpstrFilter = ctrl->fileselect.filter; @@ -1925,14 +1917,9 @@ int winctrl_handle_command(struct dlgparam *dp, UINT msg, filename[lenof(filename)-1] = '\0'; of.nMaxFile = lenof(filename); of.lpstrFileTitle = NULL; - of.lpstrInitialDir = NULL; of.lpstrTitle = ctrl->fileselect.title; of.Flags = 0; - if (ctrl->fileselect.for_writing) - ret = GetSaveFileName(&of); - else - ret = GetOpenFileName(&of); - if (ret) { + if (request_file(NULL, &of, FALSE, ctrl->fileselect.for_writing)) { SetDlgItemText(dp->hwnd, c->base_id + 1, filename); ctrl->generic.handler(ctrl, dp, dp->data, EVENT_VALCHANGE); } @@ -1949,38 +1936,36 @@ int winctrl_handle_command(struct dlgparam *dp, UINT msg, CHOOSEFONT cf; LOGFONT lf; HDC hdc; - FontSpec fs = *(FontSpec *)c->data; - + FontSpec *fs = (FontSpec *)c->data; + hdc = GetDC(0); - lf.lfHeight = -MulDiv(fs.height, + lf.lfHeight = -MulDiv(fs->height, GetDeviceCaps(hdc, LOGPIXELSY), 72); ReleaseDC(0, hdc); lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0; lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0; - lf.lfWeight = (fs.isbold ? FW_BOLD : 0); - lf.lfCharSet = fs.charset; + lf.lfWeight = (fs->isbold ? FW_BOLD : 0); + lf.lfCharSet = fs->charset; lf.lfOutPrecision = OUT_DEFAULT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = DEFAULT_QUALITY; lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE; - strncpy(lf.lfFaceName, fs.name, + strncpy(lf.lfFaceName, fs->name, sizeof(lf.lfFaceName) - 1); lf.lfFaceName[sizeof(lf.lfFaceName) - 1] = '\0'; cf.lStructSize = sizeof(cf); cf.hwndOwner = dp->hwnd; cf.lpLogFont = &lf; - cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST | - CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS; + cf.Flags = (dp->fixed_pitch_fonts ? CF_FIXEDPITCHONLY : 0) | + CF_FORCEFONTEXIST | CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS; if (ChooseFont(&cf)) { - strncpy(fs.name, lf.lfFaceName, - sizeof(fs.name) - 1); - fs.name[sizeof(fs.name) - 1] = '\0'; - fs.isbold = (lf.lfWeight == FW_BOLD); - fs.charset = lf.lfCharSet; - fs.height = cf.iPointSize / 10; + fs = fontspec_new(lf.lfFaceName, (lf.lfWeight == FW_BOLD), + cf.iPointSize / 10, lf.lfCharSet); dlg_fontsel_set(ctrl, dp, fs); + fontspec_free(fs); + ctrl->generic.handler(ctrl, dp, dp->data, EVENT_VALCHANGE); } } @@ -2020,13 +2005,12 @@ int winctrl_handle_command(struct dlgparam *dp, UINT msg, /* * This function can be called to produce context help on a - * control. Returns TRUE if it has actually launched WinHelp. + * control. Returns TRUE if it has actually launched some help. */ int winctrl_context_help(struct dlgparam *dp, HWND hwnd, int id) { int i; struct winctrl *c; - char *cmd; /* * Look up the control ID in our data. @@ -2047,9 +2031,7 @@ int winctrl_context_help(struct dlgparam *dp, HWND hwnd, int id) if (!c->ctrl || !c->ctrl->generic.helpctx.p) return 0; /* no help available for this ctrl */ - cmd = dupprintf("JI(`',`%s')", c->ctrl->generic.helpctx.p); - WinHelp(hwnd, help_path, HELP_COMMAND, (DWORD)cmd); - sfree(cmd); + launch_help(hwnd, c->ctrl->generic.helpctx.p); return 1; } @@ -2118,13 +2100,12 @@ void dlg_editbox_set(union control *ctrl, void *dlg, char const *text) SetDlgItemText(dp->hwnd, c->base_id+1, text); } -void dlg_editbox_get(union control *ctrl, void *dlg, char *buffer, int length) +char *dlg_editbox_get(union control *ctrl, void *dlg) { struct dlgparam *dp = (struct dlgparam *)dlg; struct winctrl *c = dlg_findbyctrl(dp, ctrl); assert(c && c->ctrl->generic.type == CTRL_EDITBOX); - GetDlgItemText(dp->hwnd, c->base_id+1, buffer, length); - buffer[length-1] = '\0'; + return GetDlgItemText_alloc(dp->hwnd, c->base_id+1); } /* The `listbox' functions can also apply to combo boxes. */ @@ -2212,8 +2193,13 @@ int dlg_listbox_index(union control *ctrl, void *dlg) struct dlgparam *dp = (struct dlgparam *)dlg; struct winctrl *c = dlg_findbyctrl(dp, ctrl); int msg, ret; - assert(c && c->ctrl->generic.type == CTRL_LISTBOX && - !c->ctrl->listbox.multisel); + assert(c && c->ctrl->generic.type == CTRL_LISTBOX); + if (c->ctrl->listbox.multisel) { + assert(c->ctrl->listbox.height != 0); /* not combo box */ + ret = SendDlgItemMessage(dp->hwnd, c->base_id+1, LB_GETSELCOUNT, 0, 0); + if (ret == LB_ERR || ret > 1) + return -1; + } msg = (c->ctrl->listbox.height != 0 ? LB_GETCURSEL : CB_GETCURSEL); ret = SendDlgItemMessage(dp->hwnd, c->base_id+1, msg, 0, 0); if (ret == LB_ERR) @@ -2252,49 +2238,103 @@ void dlg_text_set(union control *ctrl, void *dlg, char const *text) SetDlgItemText(dp->hwnd, c->base_id, text); } -void dlg_filesel_set(union control *ctrl, void *dlg, Filename fn) +void dlg_label_change(union control *ctrl, void *dlg, char const *text) +{ + struct dlgparam *dp = (struct dlgparam *)dlg; + struct winctrl *c = dlg_findbyctrl(dp, ctrl); + char *escaped = NULL; + int id = -1; + + assert(c); + switch (c->ctrl->generic.type) { + case CTRL_EDITBOX: + escaped = shortcut_escape(text, c->ctrl->editbox.shortcut); + id = c->base_id; + break; + case CTRL_RADIO: + escaped = shortcut_escape(text, c->ctrl->radio.shortcut); + id = c->base_id; + break; + case CTRL_CHECKBOX: + escaped = shortcut_escape(text, ctrl->checkbox.shortcut); + id = c->base_id; + break; + case CTRL_BUTTON: + escaped = shortcut_escape(text, ctrl->button.shortcut); + id = c->base_id; + break; + case CTRL_LISTBOX: + escaped = shortcut_escape(text, ctrl->listbox.shortcut); + id = c->base_id; + break; + case CTRL_FILESELECT: + escaped = shortcut_escape(text, ctrl->fileselect.shortcut); + id = c->base_id; + break; + case CTRL_FONTSELECT: + escaped = shortcut_escape(text, ctrl->fontselect.shortcut); + id = c->base_id; + break; + default: + assert(!"Can't happen"); + break; + } + if (escaped) { + SetDlgItemText(dp->hwnd, id, escaped); + sfree(escaped); + } +} + +void dlg_filesel_set(union control *ctrl, void *dlg, Filename *fn) { struct dlgparam *dp = (struct dlgparam *)dlg; struct winctrl *c = dlg_findbyctrl(dp, ctrl); assert(c && c->ctrl->generic.type == CTRL_FILESELECT); - SetDlgItemText(dp->hwnd, c->base_id+1, fn.path); + SetDlgItemText(dp->hwnd, c->base_id+1, fn->path); } -void dlg_filesel_get(union control *ctrl, void *dlg, Filename *fn) +Filename *dlg_filesel_get(union control *ctrl, void *dlg) { struct dlgparam *dp = (struct dlgparam *)dlg; struct winctrl *c = dlg_findbyctrl(dp, ctrl); + char *tmp; + Filename *ret; assert(c && c->ctrl->generic.type == CTRL_FILESELECT); - GetDlgItemText(dp->hwnd, c->base_id+1, fn->path, lenof(fn->path)); - fn->path[lenof(fn->path)-1] = '\0'; + tmp = GetDlgItemText_alloc(dp->hwnd, c->base_id+1); + ret = filename_from_str(tmp); + sfree(tmp); + return ret; } -void dlg_fontsel_set(union control *ctrl, void *dlg, FontSpec fs) +void dlg_fontsel_set(union control *ctrl, void *dlg, FontSpec *fs) { char *buf, *boldstr; struct dlgparam *dp = (struct dlgparam *)dlg; struct winctrl *c = dlg_findbyctrl(dp, ctrl); assert(c && c->ctrl->generic.type == CTRL_FONTSELECT); - *(FontSpec *)c->data = fs; /* structure copy */ + fontspec_free((FontSpec *)c->data); + c->data = fontspec_copy(fs); - boldstr = (fs.isbold ? "bold, " : ""); - if (fs.height == 0) - buf = dupprintf("Font: %s, %sdefault height", fs.name, boldstr); + boldstr = (fs->isbold ? "bold, " : ""); + if (fs->height == 0) + buf = dupprintf("Font: %s, %sdefault height", fs->name, boldstr); else - buf = dupprintf("Font: %s, %s%d-%s", fs.name, boldstr, - (fs.height < 0 ? -fs.height : fs.height), - (fs.height < 0 ? "pixel" : "point")); + buf = dupprintf("Font: %s, %s%d-%s", fs->name, boldstr, + (fs->height < 0 ? -fs->height : fs->height), + (fs->height < 0 ? "pixel" : "point")); SetDlgItemText(dp->hwnd, c->base_id+1, buf); sfree(buf); + + dlg_auto_set_fixed_pitch_flag(dp); } -void dlg_fontsel_get(union control *ctrl, void *dlg, FontSpec *fs) +FontSpec *dlg_fontsel_get(union control *ctrl, void *dlg) { struct dlgparam *dp = (struct dlgparam *)dlg; struct winctrl *c = dlg_findbyctrl(dp, ctrl); assert(c && c->ctrl->generic.type == CTRL_FONTSELECT); - *fs = *(FontSpec *)c->data; /* structure copy */ + return fontspec_copy((FontSpec *)c->data); } /* @@ -2328,6 +2368,8 @@ void dlg_set_focus(union control *ctrl, void *dlg) struct winctrl *c = dlg_findbyctrl(dp, ctrl); int id; HWND ctl; + if (!c) + return; switch (ctrl->generic.type) { case CTRL_EDITBOX: id = c->base_id + 1; break; case CTRL_RADIO: @@ -2362,7 +2404,7 @@ void dlg_beep(void *dlg) MessageBeep(0); } -void dlg_error_msg(void *dlg, char *msg) +void dlg_error_msg(void *dlg, const char *msg) { struct dlgparam *dp = (struct dlgparam *)dlg; MessageBox(dp->hwnd, msg, @@ -2432,21 +2474,60 @@ int dlg_coloursel_results(union control *ctrl, void *dlg, return 0; } -struct perctrl_privdata { - union control *ctrl; - void *data; - int needs_free; -}; +void dlg_auto_set_fixed_pitch_flag(void *dlg) +{ + struct dlgparam *dp = (struct dlgparam *)dlg; + Conf *conf = (Conf *)dp->data; + FontSpec *fs; + int quality; + HFONT hfont; + HDC hdc; + TEXTMETRIC tm; + int is_var; + + /* + * Attempt to load the current font, and see if it's + * variable-pitch. If so, start off the fixed-pitch flag for the + * dialog box as false. + * + * We assume here that any client of the dlg_* mechanism which is + * using font selectors at all is also using a normal 'Conf *' + * as dp->data. + */ + + quality = conf_get_int(conf, CONF_font_quality); + fs = conf_get_fontspec(conf, CONF_font); + + hfont = CreateFont(0, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, + DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, + CLIP_DEFAULT_PRECIS, FONT_QUALITY(quality), + FIXED_PITCH | FF_DONTCARE, fs->name); + hdc = GetDC(NULL); + if (hdc && SelectObject(hdc, hfont) && GetTextMetrics(hdc, &tm)) { + /* Note that the TMPF_FIXED_PITCH bit is defined upside down :-( */ + is_var = (tm.tmPitchAndFamily & TMPF_FIXED_PITCH); + } else { + is_var = FALSE; /* assume it's basically normal */ + } + if (hdc) + ReleaseDC(NULL, hdc); + if (hfont) + DeleteObject(hfont); -static int perctrl_privdata_cmp(void *av, void *bv) + if (is_var) + dp->fixed_pitch_fonts = FALSE; +} + +int dlg_get_fixed_pitch_flag(void *dlg) { - struct perctrl_privdata *a = (struct perctrl_privdata *)av; - struct perctrl_privdata *b = (struct perctrl_privdata *)bv; - if (a->ctrl < b->ctrl) - return -1; - else if (a->ctrl > b->ctrl) - return +1; - return 0; + struct dlgparam *dp = (struct dlgparam *)dlg; + return dp->fixed_pitch_fonts; +} + +void dlg_set_fixed_pitch_flag(void *dlg, int flag) +{ + struct dlgparam *dp = (struct dlgparam *)dlg; + dp->fixed_pitch_fonts = flag; } void dp_init(struct dlgparam *dp) @@ -2458,7 +2539,7 @@ void dp_init(struct dlgparam *dp) memset(dp->shortcuts, 0, sizeof(dp->shortcuts)); dp->hwnd = NULL; dp->wintitle = dp->errtitle = NULL; - dp->privdata = newtree234(perctrl_privdata_cmp); + dp->fixed_pitch_fonts = TRUE; } void dp_add_tree(struct dlgparam *dp, struct winctrls *wc) @@ -2469,67 +2550,6 @@ void dp_add_tree(struct dlgparam *dp, struct winctrls *wc) void dp_cleanup(struct dlgparam *dp) { - struct perctrl_privdata *p; - - if (dp->privdata) { - while ( (p = index234(dp->privdata, 0)) != NULL ) { - del234(dp->privdata, p); - if (p->needs_free) - sfree(p->data); - sfree(p); - } - freetree234(dp->privdata); - dp->privdata = NULL; - } sfree(dp->wintitle); sfree(dp->errtitle); } - -void *dlg_get_privdata(union control *ctrl, void *dlg) -{ - struct dlgparam *dp = (struct dlgparam *)dlg; - struct perctrl_privdata tmp, *p; - tmp.ctrl = ctrl; - p = find234(dp->privdata, &tmp, NULL); - if (p) - return p->data; - else - return NULL; -} - -void dlg_set_privdata(union control *ctrl, void *dlg, void *ptr) -{ - struct dlgparam *dp = (struct dlgparam *)dlg; - struct perctrl_privdata tmp, *p; - tmp.ctrl = ctrl; - p = find234(dp->privdata, &tmp, NULL); - if (!p) { - p = snew(struct perctrl_privdata); - p->ctrl = ctrl; - p->needs_free = FALSE; - add234(dp->privdata, p); - } - p->data = ptr; -} - -void *dlg_alloc_privdata(union control *ctrl, void *dlg, size_t size) -{ - struct dlgparam *dp = (struct dlgparam *)dlg; - struct perctrl_privdata tmp, *p; - tmp.ctrl = ctrl; - p = find234(dp->privdata, &tmp, NULL); - if (!p) { - p = snew(struct perctrl_privdata); - p->ctrl = ctrl; - p->needs_free = FALSE; - add234(dp->privdata, p); - } - assert(!p->needs_free); - p->needs_free = TRUE; - /* - * This is an internal allocation routine, so it's allowed to - * use smalloc directly. - */ - p->data = smalloc(size); - return p->data; -}