; CPUINFO - the window: the icon and the name with the vendor in its ; color above, the groups of the processor and of its cores and caches in ; two columns, the features under them, the buttons of TASKMAN, of the ; benchmark and of the report at the bottom. ; ==================================================================== PAD = 8 ; margins and gaps TOP = PAD + 4 ; above the icon and the name ICON = 32 ; the icons of @RESHARE ICON_CPU = 37 ; in ICONS32, as in SYSPANEL NAME_X = PAD + ICON + 12 ; the name and the capitals of the line under it centred on the icon NAME_Y = TOP + (ICON - FONT_CHAR_H - TEXT_H) / 2 ; the text: PAD from the lines around it, GAP between the parts; the ; capitals of the font with as much above as below GAP = 12 TEXT_H = FONT_CAPS_Y + FONT_CAPS_H + FONT_CAPS_Y ROW_H = 20 ROW_TEXT_DY = (ROW_H - TEXT_H) / 2 FLAG_GAP = 12 ; between the features BOLD_W = FONT_CHAR_W + 1 ; a bold character, a pixel apart FONT = 0xB0000000 ; zero terminated, 8x16 UTF-8 BOLD_FONT = 0x30000000 ; 8x16 UTF-8, esi characters ; a group: a frame with its title over the top line (group_box.inc); the ; capitals of the text GAP from the title and from the frame TEXT_TOP = GROUP_TITLE_BELOW + GAP - FONT_CAPS_Y TEXT_BOTTOM = FONT_CAPS_Y + FONT_CAPS_H + GAP + GROUP_LINES GROUP_GAP = GAP + GROUP_TITLE_ABOVE GROUP_Y = TOP + ICON + GAP + GROUP_TITLE_ABOVE ROWS = 8 ; in a group GROUP_H = TEXT_TOP + (ROWS - 1) * ROW_H + TEXT_BOTTOM ; in every group the labels and the values in the same columns, as wide ; as the longest label and value need VALUE_CHARS = 11 ; "10 x 1.2 MB", "1Fh, 8..26h" LABEL_GAP = 2 * FONT_CHAR_W ; two spaces after the label LABEL_DX = GROUP_LINES + GAP - 1 ; from the left of the group: GAP with the empty column of a letter VALUE_DX = LABEL_DX + label_max * FONT_CHAR_W + LABEL_GAP VALUE_W = VALUE_CHARS * FONT_CHAR_W GROUP_W = VALUE_DX + VALUE_W + GAP + GROUP_LINES - 1 ; the groups, a RECT is x, y, width, height; the one of the features ; under them, its height by window_init PROCESSOR_BOX RECT PAD, GROUP_Y, GROUP_W, GROUP_H CORES_BOX RECT PAD + GROUP_W + GROUP_GAP, GROUP_Y, GROUP_W, GROUP_H FEATURES_BOX RECT PAD, GROUP_Y + GROUP_H + GROUP_GAP, CORES_BOX.X + GROUP_W - PAD, 0 FIRST_FEATURE = ((FEATURES_BOX.X + VALUE_DX) shl 16) + FEATURES_BOX.Y + TEXT_TOP ; the window CLIENT_W = CORES_BOX.X + GROUP_W + PAD WINDOW_W = CLIENT_W + 9 ; borders 5 + 5, the kernel adds a pixel WINDOW_BOTTOM = 4 ; border 5, the same pixel; the skin on top WINDOW_STYLE = 0x34000000 ; skinned, fixed size, caption, client coordinates ; the name in bold fits up to NAME_CHARS: of the BRAND_CHARS of CPUID ; the real names, their spaces squeezed, have 46 at most ("AMD Athlon(tm) ; 64 X2 Dual Core Processor 4800+"); past the window the kernel cuts it NAME_CHARS = 47 assert NAME_X + NAME_CHARS * BOLD_W <= CLIENT_W - PAD ; the buttons: TASKMAN and the benchmark at the left, the report at the ; right. Their captions: the capitals and the underline a row under them ; in the middle BTN_H = 24 UNDERLINE_DY = FONT_CAPS_Y + FONT_CAPS_H + 1 BTN_TEXT_DY = (BTN_H - FONT_CAPS_H - 2) / 2 - FONT_CAPS_Y TASKMAN_W = sz_taskman.chars * FONT_CHAR_W + 2 * PAD TASKMAN_X = PAD BENCH_W = sz_bench.chars * FONT_CHAR_W + 2 * PAD BENCH_X = TASKMAN_X + TASKMAN_W + GAP REPORT_W = sz_report.chars * FONT_CHAR_W + 2 * PAD REPORT_X = CLIENT_W - PAD - REPORT_W assert BENCH_X + BENCH_W + GAP <= REPORT_X ; a button, its key and what it does struct BUTTON x_width dd ? ; x shl 16 + width key db ? ; the scancode of its first letter, the id of the button caption dd ? proc dd ? ; what it does, esi = arg arg dd ? ends ; a BUTTON in a table macro button_row x, width, key, caption, proc, arg { local start start: dd (x) shl 16 + (width) db key dd caption, proc, arg assert $ - start = sizeof.BUTTON } ; a row of a group: its label and its value struct ROW text dd ? ; the label get dd ? ; the procedure of the value arg dd ? ; eax for it pos dd ? ; x shl 16 + y of the value ends ; ==================================================================== ; The parts of the name of the CPU: the vendor in it and its color; the ; features laid out as draw_window draws them: the height of their group ; and the buttons under it. window_init: imul eax, [vendor_id], sizeof.VENDOR mov ecx, [vendors + eax + VENDOR.color] mov [name_color], ecx mov esi, [vendors + eax + VENDOR.name] call brand_find mov [name_vendor], edx mov [name_vendor_end], edi mov esi, edi call str_skip dec esi mov [name_end], esi mov [feature_at], FIRST_FEATURE mov esi, flags .next: call place_feature jnc .next ; the group down to GAP under the last line, the buttons GAP under ; the group movzx eax, word [feature_at] add eax, TEXT_BOTTOM - FEATURES_BOX.Y lea ecx, [eax + FEATURES_BOX.Y shl 16] mov [features_group + GROUP_BOX.y_height], ecx add eax, FEATURES_BOX.Y + GAP mov [button_y], eax ret ; ==================================================================== draw_window: mcall SF_STYLE_SETTINGS, SSF_GET_COLORS, sc, sizeof.system_colors mcall SF_REDRAW, SSF_BEGIN_DRAW ; the window down to PAD under the buttons, in the centre of the ; screen; the kernel takes its place only the first time, and ; keeps it on the screen mcall SF_STYLE_SETTINGS, SSF_GET_SKIN_HEIGHT lea esi, [eax + BTN_H + PAD + WINDOW_BOTTOM] add esi, [button_y] mcall SF_GET_SCREEN_SIZE movzx ecx, ax sub ecx, esi shr ecx, 1 shl ecx, 16 add ecx, esi shr eax, 16 sub eax, WINDOW_W shr eax, 1 shl eax, 16 lea ebx, [eax + WINDOW_W] mov edx, [sc.work] or edx, WINDOW_STYLE mcall SF_CREATE_WINDOW, , , , 0, sz_title mcall SF_THREAD_INFO, pinfo, -1 test [pinfo.wnd_state], WND_ROLLED_UP jnz .done ; the icon, its transparent pixels in the window color; their ; alpha stays 0 for the next redraw. No icon: all of them, the ; buffer stays zero mov edi, icon_buf mov ecx, ICON * ICON mov eax, [sc.work] and eax, 0xFFFFFF .pixel: cmp byte [edi + 3], 0 ; its alpha jne .opaque mov [edi], eax .opaque: add edi, 4 loop .pixel mcall SF_PUT_IMAGE_EXT, icon_buf, , , 32, 0, 0 ; the name of the CPU in bold in three parts, each drawn once ; (font smoothing): before the vendor, the vendor in its color, the ; rest; the vendor and the code name under it in regular mov ebx, (NAME_X shl 16) + NAME_Y mov ecx, [sc.work_text] mov edx, [brand_ptr] mov edi, [name_vendor] call draw_bold mov ecx, [name_color] mov edi, [name_vendor_end] call draw_bold mov ecx, [sc.work_text] mov edi, [name_end] call draw_bold mov ebx, (NAME_X shl 16) + NAME_Y + FONT_CHAR_H mov edx, vendor_line call draw_text ; the groups mov edi, groups .group: call group_box add edi, sizeof.GROUP_BOX cmp edi, groups_end jb .group ; the rows: the label, then the value mov esi, rows .row: mov ebx, [esi + ROW.pos] sub ebx, (VALUE_DX - LABEL_DX) shl 16 mov edx, [esi + ROW.text] call draw_text ; the getter changes all the registers push esi mov eax, [esi + ROW.arg] mov edi, text_buf call [esi + ROW.get] pop esi mov ebx, [esi + ROW.pos] mov edx, text_buf call draw_text add esi, sizeof.ROW cmp esi, rows_end jb .row ; the features, the label of a group in the column of the labels ; on the line of its first one mov [feature_at], FIRST_FEATURE mov esi, flags .feature: call place_feature jc .buttons call draw_text test ebp, ebp jz .feature movzx ebx, bx add ebx, (FEATURES_BOX.X + LABEL_DX) shl 16 mov edx, ebp call draw_text jmp .feature ; the buttons, their captions PAD from the left, the first letter, ; the key, underlined .buttons: mov edi, buttons .button: ; the button, the kernel makes it a pixel wider and higher mov ebx, [edi + BUTTON.x_width] dec ebx mov ecx, [button_y] shl ecx, 16 add ecx, BTN_H - 1 movzx edx, [edi + BUTTON.key] mcall SF_DEFINE_BUTTON, , , , [sc.work_light] ; its caption mov ebx, [edi + BUTTON.x_width] and ebx, 0xFFFF0000 add ebx, [button_y] add ebx, (PAD shl 16) + BTN_TEXT_DY mov edx, [edi + BUTTON.caption] call draw_text ; the line under its first letter mov ecx, ebx shl ecx, 16 add ecx, (UNDERLINE_DY shl 16) + 1 and ebx, 0xFFFF0000 add ebx, FONT_CHAR_W mcall SF_DRAW_RECT, , , [sc.work_text] add edi, sizeof.BUTTON cmp edi, buttons_end jb .button .done: mcall SF_REDRAW, SSF_END_DRAW ret ; ==================================================================== ; ebx = x shl 16 + y, edx -> the text in UTF-8: in regular, work_text; ; changes eax, ecx draw_text: mov ecx, [sc.work_text] or ecx, FONT mcall SF_DRAW_TEXT ret ; ebx = x shl 16 + y, ecx = the color, edx -> the text in UTF-8, edi -> ; its end: bold, each character twice a pixel apart; out: ebx past the ; text on the same line, edx at its end; changes eax, ecx draw_bold: push esi or ecx, BOLD_FONT mov esi, 1 .char: cmp edx, edi jae .done mcall SF_DRAW_TEXT add ebx, 1 shl 16 mcall SF_DRAW_TEXT add ebx, (BOLD_W - 1) shl 16 ; past its first byte and the ones that go on with it: 10xxxxxx .tail: inc edx mov al, [edx] and al, 0xC0 cmp al, 0x80 je .tail jmp .char .done: pop esi ret ; ==================================================================== ; The features of the CPU flow in lines in the column of the values, ; each group from a new line. esi -> into flags: the next feature the CPU ; has, placed at feature_at; out: esi and feature_at past it, ebx = its ; place, edx -> its name, ebp -> the label of its group if it is the ; first one of it there, else 0; CF = 1 after the last one; changes eax, ; ecx place_feature: call next_feature jc .done mov ebx, [feature_at] ; its width imul ecx, FONT_CHAR_W ; the first of a group: from a new line, unless it is the first ; one of all, nothing placed yet test ebp, ebp jz .fit cmp ebx, FIRST_FEATURE je .fit call .new_line ; a new line if it does not fit in this one, GAP from the right ; line of the frame .fit: mov eax, ebx shr eax, 16 add eax, ecx cmp eax, FEATURES_BOX.X + FEATURES_BOX.W - GROUP_LINES - GAP jbe .put call .new_line .put: lea eax, [ecx + FLAG_GAP] shl eax, 16 add eax, ebx mov [feature_at], eax clc .done: ret .new_line: movzx ebx, bx add ebx, ((FEATURES_BOX.X + VALUE_DX) shl 16) + ROW_H ret ; esi -> into flags: the next feature the CPU has: edx -> its name, ; ecx = its length, esi past it, ebp -> the label of its group if it is ; the first one of it there, else 0; CF = 1 after the last one; changes ; eax next_feature: movi ebp, 0 .next: lodsb cmp al, FLAGS_END je .end cmp al, FLAGS_GROUP jne .flag lodsd mov ebp, eax jmp .next ; the name, skipped if the CPU has not the feature .flag: movzx eax, al mov edx, esi call str_skip bt [cpu_regs], eax jnc .next clc ret .end: stc ret ; ==================================================================== ; a row: the label, the procedure of the value and its argument, the ; group and the line in it macro row text, get, arg, box, line { assert line < ROWS dd text, get, arg dd ((box#.X + VALUE_DX) shl 16) + box#.Y + TEXT_TOP + line * ROW_H } ; the buttons: what it does, with what buttons: ; x width key caption proc arg button_row TASKMAN_X, TASKMAN_W, sz_taskman.key, sz_taskman, run_program, sz_taskman_path button_row BENCH_X, BENCH_W, sz_bench.key, sz_bench, run_program, sz_bench_path button_row REPORT_X, REPORT_W, sz_report.key, sz_report, report, 0 buttons_end: ; the groups, the titles over the labels; the height of the features by ; window_init groups: ; x y width height title title_x colors group_box_row PROCESSOR_BOX.X, PROCESSOR_BOX.Y, PROCESSOR_BOX.W, PROCESSOR_BOX.H, sz_processor, LABEL_DX, sc group_box_row CORES_BOX.X, CORES_BOX.Y, CORES_BOX.W, CORES_BOX.H, sz_cores_cache, LABEL_DX, sc features_group: group_box_row FEATURES_BOX.X, FEATURES_BOX.Y, FEATURES_BOX.W, 0, sz_features, LABEL_DX, sc groups_end: rows: row sz_family, val_id, family, PROCESSOR_BOX, 0 row sz_model, val_id, model, PROCESSOR_BOX, 1 row sz_stepping, val_id, stepping, PROCESSOR_BOX, 2 row sz_signature, val_hex8, signature, PROCESSOR_BOX, 3 row sz_freq, val_mhz, freq_mhz, PROCESSOR_BOX, 4 row sz_mult, val_mult, mult10, PROCESSOR_BOX, 5 row sz_bus, val_mhz10, bus10, PROCESSOR_BOX, 6 row sz_temp, val_deg, max_temp, PROCESSOR_BOX, 7 row sz_cores, val_count, cores, CORES_BOX, 0 row sz_threads, val_uint, threads, CORES_BOX, 1 row sz_l1d, val_cache, cache_l1d, CORES_BOX, 2 row sz_l1i, val_cache, cache_l1i, CORES_BOX, 3 row sz_line, val_bytes, cache_l1d.line, CORES_BOX, 4 row sz_l2, val_cache, cache_l2, CORES_BOX, 5 row sz_l3, val_cache, cache_l3, CORES_BOX, 6 row sz_levels, val_levels, 0, CORES_BOX, 7 rows_end: assert (rows_end - rows) / sizeof.ROW = 2 * ROWS uglobal align 4 button_y dd ? feature_at dd ? ; the place of the next feature name_color dd ? ; of the vendor in the name of the CPU name_vendor dd ? ; -> the vendor in the name name_vendor_end dd ? ; -> past it name_end dd ? ; -> the end of the name endg