| @@ -129,26 +129,27 @@ usage(void) | | | @@ -129,26 +129,27 @@ usage(void) |
129 | " --left-of <output>\n" | | 129 | " --left-of <output>\n" |
130 | " --right-of <output>\n" | | 130 | " --right-of <output>\n" |
131 | " --above <output>\n" | | 131 | " --above <output>\n" |
132 | " --below <output>\n" | | 132 | " --below <output>\n" |
133 | " --same-as <output>\n" | | 133 | " --same-as <output>\n" |
134 | " --set <property> <value>\n" | | 134 | " --set <property> <value>\n" |
135 | " --scale <x>x<y>\n" | | 135 | " --scale <x>x<y>\n" |
136 | " --scale-from <w>x<h>\n" | | 136 | " --scale-from <w>x<h>\n" |
137 | " --transform <a>,<b>,<c>,<d>,<e>,<f>,<g>,<h>,<i>\n" | | 137 | " --transform <a>,<b>,<c>,<d>,<e>,<f>,<g>,<h>,<i>\n" |
138 | " --off\n" | | 138 | " --off\n" |
139 | " --crtc <crtc>\n" | | 139 | " --crtc <crtc>\n" |
140 | " --panning <w>x<h>[+<x>+<y>[/<track:w>x<h>+<x>+<y>[/<border:l>/<t>/<r>/<b>]]]\n" | | 140 | " --panning <w>x<h>[+<x>+<y>[/<track:w>x<h>+<x>+<y>[/<border:l>/<t>/<r>/<b>]]]\n" |
141 | " --gamma <r>:<g>:<b>\n" | | 141 | " --gamma <r>:<g>:<b>\n" |
| | | 142 | " --brightness <value>\n" |
142 | " --primary\n" | | 143 | " --primary\n" |
143 | " --noprimary\n" | | 144 | " --noprimary\n" |
144 | " --newmode <name> <clock MHz>\n" | | 145 | " --newmode <name> <clock MHz>\n" |
145 | " <hdisp> <hsync-start> <hsync-end> <htotal>\n" | | 146 | " <hdisp> <hsync-start> <hsync-end> <htotal>\n" |
146 | " <vdisp> <vsync-start> <vsync-end> <vtotal>\n" | | 147 | " <vdisp> <vsync-start> <vsync-end> <vtotal>\n" |
147 | " [flags...]\n" | | 148 | " [flags...]\n" |
148 | " Valid flags: +HSync -HSync +VSync -VSync\n" | | 149 | " Valid flags: +HSync -HSync +VSync -VSync\n" |
149 | " +CSync -CSync CSync Interlace DoubleScan\n" | | 150 | " +CSync -CSync CSync Interlace DoubleScan\n" |
150 | " --rmmode <name>\n" | | 151 | " --rmmode <name>\n" |
151 | " --addmode <output> <name>\n" | | 152 | " --addmode <output> <name>\n" |
152 | " --delmode <output> <name>\n" | | 153 | " --delmode <output> <name>\n" |
153 | " --listproviders\n" | | 154 | " --listproviders\n" |
154 | " --setprovideroutputsource <prov-xid> <source-xid>\n" | | 155 | " --setprovideroutputsource <prov-xid> <source-xid>\n" |
| @@ -1384,27 +1385,27 @@ set_panning (void) | | | @@ -1384,27 +1385,27 @@ set_panning (void) |
1384 | if (! output->crtc_info->panning_info) | | 1385 | if (! output->crtc_info->panning_info) |
1385 | output->crtc_info->panning_info = malloc (sizeof(XRRPanning)); | | 1386 | output->crtc_info->panning_info = malloc (sizeof(XRRPanning)); |
1386 | memcpy (output->crtc_info->panning_info, &output->panning, sizeof(XRRPanning)); | | 1387 | memcpy (output->crtc_info->panning_info, &output->panning, sizeof(XRRPanning)); |
1387 | output->crtc_info->changing = 1; | | 1388 | output->crtc_info->changing = 1; |
1388 | } | | 1389 | } |
1389 | } | | 1390 | } |
1390 | | | 1391 | |
1391 | static void | | 1392 | static void |
1392 | set_gamma(void) | | 1393 | set_gamma(void) |
1393 | { | | 1394 | { |
1394 | output_t *output; | | 1395 | output_t *output; |
1395 | | | 1396 | |
1396 | for (output = all_outputs; output; output = output->next) { | | 1397 | for (output = all_outputs; output; output = output->next) { |
1397 | int i, size, shift; | | 1398 | int i, size; |
1398 | crtc_t *crtc; | | 1399 | crtc_t *crtc; |
1399 | XRRCrtcGamma *crtc_gamma; | | 1400 | XRRCrtcGamma *crtc_gamma; |
1400 | float gammaRed; | | 1401 | float gammaRed; |
1401 | float gammaGreen; | | 1402 | float gammaGreen; |
1402 | float gammaBlue; | | 1403 | float gammaBlue; |
1403 | | | 1404 | |
1404 | if (!(output->changes & changes_gamma)) | | 1405 | if (!(output->changes & changes_gamma)) |
1405 | continue; | | 1406 | continue; |
1406 | | | 1407 | |
1407 | if (!output->crtc_info) { | | 1408 | if (!output->crtc_info) { |
1408 | fatal("Need crtc to set gamma on.\n"); | | 1409 | fatal("Need crtc to set gamma on.\n"); |
1409 | continue; | | 1410 | continue; |
1410 | } | | 1411 | } |
| @@ -1419,75 +1420,64 @@ set_gamma(void) | | | @@ -1419,75 +1420,64 @@ set_gamma(void) |
1419 | } | | 1420 | } |
1420 | | | 1421 | |
1421 | /* | | 1422 | /* |
1422 | * The gamma-correction lookup table managed through XRR[GS]etCrtcGamma | | 1423 | * The gamma-correction lookup table managed through XRR[GS]etCrtcGamma |
1423 | * is 2^n in size, where 'n' is the number of significant bits in | | 1424 | * is 2^n in size, where 'n' is the number of significant bits in |
1424 | * the X Color. Because an X Color is 16 bits, size cannot be larger | | 1425 | * the X Color. Because an X Color is 16 bits, size cannot be larger |
1425 | * than 2^16. | | 1426 | * than 2^16. |
1426 | */ | | 1427 | */ |
1427 | if (size > 65536) { | | 1428 | if (size > 65536) { |
1428 | fatal("Gamma correction table is impossibly large.\n"); | | 1429 | fatal("Gamma correction table is impossibly large.\n"); |
1429 | continue; | | 1430 | continue; |
1430 | } | | 1431 | } |
1431 | | | 1432 | |
1432 | /* | | | |
1433 | * The hardware color lookup table has a number of significant | | | |
1434 | * bits equal to ffs(size) - 1; compute all values so that | | | |
1435 | * they are in the range [0,size) then shift the values so | | | |
1436 | * that they occupy the MSBs of the 16-bit X Color. | | | |
1437 | */ | | | |
1438 | shift = 16 - (ffs(size) - 1); | | | |
1439 | | | | |
1440 | crtc_gamma = XRRAllocGamma(size); | | 1433 | crtc_gamma = XRRAllocGamma(size); |
1441 | if (!crtc_gamma) { | | 1434 | if (!crtc_gamma) { |
1442 | fatal("Gamma allocation failed.\n"); | | 1435 | fatal("Gamma allocation failed.\n"); |
1443 | continue; | | 1436 | continue; |
1444 | } | | 1437 | } |
1445 | | | 1438 | |
1446 | if (output->gamma.red == 0.0) | | 1439 | if (output->gamma.red == 0.0) |
1447 | output->gamma.red = 1.0; | | 1440 | output->gamma.red = 1.0; |
1448 | if (output->gamma.green == 0.0) | | 1441 | if (output->gamma.green == 0.0) |
1449 | output->gamma.green = 1.0; | | 1442 | output->gamma.green = 1.0; |
1450 | if (output->gamma.blue == 0.0) | | 1443 | if (output->gamma.blue == 0.0) |
1451 | output->gamma.blue = 1.0; | | 1444 | output->gamma.blue = 1.0; |
1452 | | | 1445 | |
1453 | gammaRed = 1.0 / output->gamma.red; | | 1446 | gammaRed = 1.0 / output->gamma.red; |
1454 | gammaGreen = 1.0 / output->gamma.green; | | 1447 | gammaGreen = 1.0 / output->gamma.green; |
1455 | gammaBlue = 1.0 / output->gamma.blue; | | 1448 | gammaBlue = 1.0 / output->gamma.blue; |
1456 | | | 1449 | |
1457 | for (i = 0; i < size; i++) { | | 1450 | for (i = 0; i < size; i++) { |
1458 | if (gammaRed == 1.0 && output->brightness == 1.0) | | 1451 | if (gammaRed == 1.0 && output->brightness == 1.0) |
1459 | crtc_gamma->red[i] = i; | | 1452 | crtc_gamma->red[i] = (double)i / (double)(size - 1) * 65535.0; |
1460 | else | | 1453 | else |
1461 | crtc_gamma->red[i] = dmin(pow((double)i/(double)(size - 1), | | 1454 | crtc_gamma->red[i] = dmin(pow((double)i/(double)(size - 1), |
1462 | gammaRed) * output->brightness, | | 1455 | gammaRed) * output->brightness, |
1463 | 1.0) * (double)(size - 1); | | 1456 | 1.0) * 65535.0; |
1464 | crtc_gamma->red[i] <<= shift; | | | |
1465 | | | 1457 | |
1466 | if (gammaGreen == 1.0 && output->brightness == 1.0) | | 1458 | if (gammaGreen == 1.0 && output->brightness == 1.0) |
1467 | crtc_gamma->green[i] = i; | | 1459 | crtc_gamma->green[i] = (double)i / (double)(size - 1) * 65535.0; |
1468 | else | | 1460 | else |
1469 | crtc_gamma->green[i] = dmin(pow((double)i/(double)(size - 1), | | 1461 | crtc_gamma->green[i] = dmin(pow((double)i/(double)(size - 1), |
1470 | gammaGreen) * output->brightness, | | 1462 | gammaGreen) * output->brightness, |
1471 | 1.0) * (double)(size - 1); | | 1463 | 1.0) * 65535.0; |
1472 | crtc_gamma->green[i] <<= shift; | | | |
1473 | | | 1464 | |
1474 | if (gammaBlue == 1.0 && output->brightness == 1.0) | | 1465 | if (gammaBlue == 1.0 && output->brightness == 1.0) |
1475 | crtc_gamma->blue[i] = i; | | 1466 | crtc_gamma->blue[i] = (double)i / (double)(size - 1) * 65535.0; |
1476 | else | | 1467 | else |
1477 | crtc_gamma->blue[i] = dmin(pow((double)i/(double)(size - 1), | | 1468 | crtc_gamma->blue[i] = dmin(pow((double)i/(double)(size - 1), |
1478 | gammaBlue) * output->brightness, | | 1469 | gammaBlue) * output->brightness, |
1479 | 1.0) * (double)(size - 1); | | 1470 | 1.0) * 65535.0; |
1480 | crtc_gamma->blue[i] <<= shift; | | | |
1481 | } | | 1471 | } |
1482 | | | 1472 | |
1483 | XRRSetCrtcGamma(dpy, crtc->crtc.xid, crtc_gamma); | | 1473 | XRRSetCrtcGamma(dpy, crtc->crtc.xid, crtc_gamma); |
1484 | | | 1474 | |
1485 | free(crtc_gamma); | | 1475 | free(crtc_gamma); |
1486 | } | | 1476 | } |
1487 | } | | 1477 | } |
1488 | | | 1478 | |
1489 | static void | | 1479 | static void |
1490 | set_primary(void) | | 1480 | set_primary(void) |
1491 | { | | 1481 | { |
1492 | output_t *output; | | 1482 | output_t *output; |
1493 | | | 1483 | |
| @@ -2572,26 +2562,28 @@ main (int argc, char **argv) | | | @@ -2572,26 +2562,28 @@ main (int argc, char **argv) |
2572 | Bool have_pixel_size = False; | | 2562 | Bool have_pixel_size = False; |
2573 | int ret = 0; | | 2563 | int ret = 0; |
2574 | output_t *config_output = NULL; | | 2564 | output_t *config_output = NULL; |
2575 | Bool setit_1_2 = False; | | 2565 | Bool setit_1_2 = False; |
2576 | Bool query_1_2 = False; | | 2566 | Bool query_1_2 = False; |
2577 | Bool modeit = False; | | 2567 | Bool modeit = False; |
2578 | Bool propit = False; | | 2568 | Bool propit = False; |
2579 | Bool query_1 = False; | | 2569 | Bool query_1 = False; |
2580 | Bool list_providers = False; | | 2570 | Bool list_providers = False; |
2581 | Bool provsetoutsource = False; | | 2571 | Bool provsetoutsource = False; |
2582 | Bool provsetoffsink = False; | | 2572 | Bool provsetoffsink = False; |
2583 | int major, minor; | | 2573 | int major, minor; |
2584 | Bool current = False; | | 2574 | Bool current = False; |
| | | 2575 | Bool toggle_x = False; |
| | | 2576 | Bool toggle_y = False; |
2585 | | | 2577 | |
2586 | program_name = argv[0]; | | 2578 | program_name = argv[0]; |
2587 | for (i = 1; i < argc; i++) { | | 2579 | for (i = 1; i < argc; i++) { |
2588 | if (!strcmp ("-display", argv[i]) || !strcmp ("--display", argv[i]) || | | 2580 | if (!strcmp ("-display", argv[i]) || !strcmp ("--display", argv[i]) || |
2589 | !strcmp ("-d", argv[i])) { | | 2581 | !strcmp ("-d", argv[i])) { |
2590 | if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); | | 2582 | if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); |
2591 | display_name = argv[i]; | | 2583 | display_name = argv[i]; |
2592 | continue; | | 2584 | continue; |
2593 | } | | 2585 | } |
2594 | if (!strcmp("-help", argv[i]) || !strcmp("--help", argv[i])) { | | 2586 | if (!strcmp("-help", argv[i]) || !strcmp("--help", argv[i])) { |
2595 | usage(); | | 2587 | usage(); |
2596 | exit(0); | | 2588 | exit(0); |
2597 | } | | 2589 | } |
| @@ -2640,33 +2632,33 @@ main (int argc, char **argv) | | | @@ -2640,33 +2632,33 @@ main (int argc, char **argv) |
2640 | setit_1_2 = True; | | 2632 | setit_1_2 = True; |
2641 | } | | 2633 | } |
2642 | action_requested = True; | | 2634 | action_requested = True; |
2643 | continue; | | 2635 | continue; |
2644 | } | | 2636 | } |
2645 | | | 2637 | |
2646 | if (!strcmp ("-v", argv[i]) || !strcmp ("--version", argv[i])) { | | 2638 | if (!strcmp ("-v", argv[i]) || !strcmp ("--version", argv[i])) { |
2647 | version = True; | | 2639 | version = True; |
2648 | action_requested = True; | | 2640 | action_requested = True; |
2649 | continue; | | 2641 | continue; |
2650 | } | | 2642 | } |
2651 | | | 2643 | |
2652 | if (!strcmp ("-x", argv[i])) { | | 2644 | if (!strcmp ("-x", argv[i])) { |
2653 | reflection |= RR_Reflect_X; | | 2645 | toggle_x = True; |
2654 | setit = True; | | 2646 | setit = True; |
2655 | action_requested = True; | | 2647 | action_requested = True; |
2656 | continue; | | 2648 | continue; |
2657 | } | | 2649 | } |
2658 | if (!strcmp ("-y", argv[i])) { | | 2650 | if (!strcmp ("-y", argv[i])) { |
2659 | reflection |= RR_Reflect_Y; | | 2651 | toggle_y = True; |
2660 | setit = True; | | 2652 | setit = True; |
2661 | action_requested = True; | | 2653 | action_requested = True; |
2662 | continue; | | 2654 | continue; |
2663 | } | | 2655 | } |
2664 | if (!strcmp ("--screen", argv[i])) { | | 2656 | if (!strcmp ("--screen", argv[i])) { |
2665 | if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); | | 2657 | if (++i >= argc) argerr ("%s requires an argument\n", argv[i-1]); |
2666 | screen = check_strtol(argv[i]); | | 2658 | screen = check_strtol(argv[i]); |
2667 | if (screen < 0) argerr ("--screen argument must be nonnegative\n"); | | 2659 | if (screen < 0) argerr ("--screen argument must be nonnegative\n"); |
2668 | continue; | | 2660 | continue; |
2669 | } | | 2661 | } |
2670 | if (!strcmp ("-q", argv[i]) || !strcmp ("--query", argv[i])) { | | 2662 | if (!strcmp ("-q", argv[i]) || !strcmp ("--query", argv[i])) { |
2671 | query = True; | | 2663 | query = True; |
2672 | continue; | | 2664 | continue; |
| @@ -3256,33 +3248,33 @@ main (int argc, char **argv) | | | @@ -3256,33 +3248,33 @@ main (int argc, char **argv) |
3256 | type = actual_type; | | 3248 | type = actual_type; |
3257 | format = actual_format; | | 3249 | format = actual_format; |
3258 | } | | 3250 | } |
3259 | else if (type == AnyPropertyType && | | 3251 | else if (type == AnyPropertyType && |
3260 | (sscanf (prop->value, "%d", &int_value) == 1 || | | 3252 | (sscanf (prop->value, "%d", &int_value) == 1 || |
3261 | sscanf (prop->value, "0x%x", &int_value) == 1)) | | 3253 | sscanf (prop->value, "0x%x", &int_value) == 1)) |
3262 | { | | 3254 | { |
3263 | type = XA_INTEGER; | | 3255 | type = XA_INTEGER; |
3264 | ulong_value = int_value; | | 3256 | ulong_value = int_value; |
3265 | data = (unsigned char *) &ulong_value; | | 3257 | data = (unsigned char *) &ulong_value; |
3266 | nelements = 1; | | 3258 | nelements = 1; |
3267 | format = 32; | | 3259 | format = 32; |
3268 | } | | 3260 | } |
3269 | else if ((type == XA_ATOM)) | | 3261 | else if (type == XA_ATOM) |
3270 | { | | 3262 | { |
3271 | ulong_value = XInternAtom (dpy, prop->value, False); | | 3263 | ulong_value = XInternAtom (dpy, prop->value, False); |
3272 | data = (unsigned char *) &ulong_value; | | 3264 | data = (unsigned char *) &ulong_value; |
3273 | nelements = 1; | | 3265 | nelements = 1; |
3274 | } | | 3266 | } |
3275 | else if ((type == XA_STRING || type == AnyPropertyType)) | | 3267 | else if (type == XA_STRING || type == AnyPropertyType) |
3276 | { | | 3268 | { |
3277 | type = XA_STRING; | | 3269 | type = XA_STRING; |
3278 | data = (unsigned char *) prop->value; | | 3270 | data = (unsigned char *) prop->value; |
3279 | nelements = strlen (prop->value); | | 3271 | nelements = strlen (prop->value); |
3280 | format = 8; | | 3272 | format = 8; |
3281 | } | | 3273 | } |
3282 | else | | 3274 | else |
3283 | continue; | | 3275 | continue; |
3284 | XRRChangeOutputProperty (dpy, output->output.xid, | | 3276 | XRRChangeOutputProperty (dpy, output->output.xid, |
3285 | name, type, format, PropModeReplace, | | 3277 | name, type, format, PropModeReplace, |
3286 | data, nelements); | | 3278 | data, nelements); |
3287 | free (malloced_data); | | 3279 | free (malloced_data); |
3288 | } | | 3280 | } |
| @@ -3825,26 +3817,29 @@ main (int argc, char **argv) | | | @@ -3825,26 +3817,29 @@ main (int argc, char **argv) |
3825 | rates = XRRConfigRates (sc, i, &nrate); | | 3817 | rates = XRRConfigRates (sc, i, &nrate); |
3826 | if (nrate) printf (" "); | | 3818 | if (nrate) printf (" "); |
3827 | for (j = 0; j < nrate; j++) | | 3819 | for (j = 0; j < nrate; j++) |
3828 | printf ("%c%-4d", | | 3820 | printf ("%c%-4d", |
3829 | i == current_size && rates[j] == current_rate ? '*' : ' ', | | 3821 | i == current_size && rates[j] == current_rate ? '*' : ' ', |
3830 | rates[j]); | | 3822 | rates[j]); |
3831 | printf ("\n"); | | 3823 | printf ("\n"); |
3832 | } | | 3824 | } |
3833 | } | | 3825 | } |
3834 | | | 3826 | |
3835 | { | | 3827 | { |
3836 | Rotation rotations = XRRConfigRotations(sc, ¤t_rotation); | | 3828 | Rotation rotations = XRRConfigRotations(sc, ¤t_rotation); |
3837 | | | 3829 | |
| | | 3830 | if (toggle_x && !(current_rotation & RR_Reflect_X)) reflection |= RR_Reflect_X; |
| | | 3831 | if (toggle_y && !(current_rotation & RR_Reflect_Y)) reflection |= RR_Reflect_Y; |
| | | 3832 | |
3838 | if (query) { | | 3833 | if (query) { |
3839 | printf("Current rotation - %s\n", | | 3834 | printf("Current rotation - %s\n", |
3840 | rotation_name (current_rotation)); | | 3835 | rotation_name (current_rotation)); |
3841 | | | 3836 | |
3842 | printf("Current reflection - %s\n", | | 3837 | printf("Current reflection - %s\n", |
3843 | reflection_name (current_rotation)); | | 3838 | reflection_name (current_rotation)); |
3844 | | | 3839 | |
3845 | printf ("Rotations possible - "); | | 3840 | printf ("Rotations possible - "); |
3846 | for (i = 0; i < 4; i ++) { | | 3841 | for (i = 0; i < 4; i ++) { |
3847 | if ((rotations >> i) & 1) printf("%s ", direction[i]); | | 3842 | if ((rotations >> i) & 1) printf("%s ", direction[i]); |
3848 | } | | 3843 | } |
3849 | printf ("\n"); | | 3844 | printf ("\n"); |
3850 | | | 3845 | |
| @@ -3862,30 +3857,26 @@ main (int argc, char **argv) | | | @@ -3862,30 +3857,26 @@ main (int argc, char **argv) |
3862 | | | 3857 | |
3863 | if (verbose) { | | 3858 | if (verbose) { |
3864 | printf("Setting size to %d, rotation to %s\n", size, direction[rot]); | | 3859 | printf("Setting size to %d, rotation to %s\n", size, direction[rot]); |
3865 | | | 3860 | |
3866 | printf ("Setting reflection on "); | | 3861 | printf ("Setting reflection on "); |
3867 | if (reflection) | | 3862 | if (reflection) |
3868 | { | | 3863 | { |
3869 | if (reflection & RR_Reflect_X) printf ("X Axis "); | | 3864 | if (reflection & RR_Reflect_X) printf ("X Axis "); |
3870 | if (reflection & RR_Reflect_Y) printf ("Y Axis"); | | 3865 | if (reflection & RR_Reflect_Y) printf ("Y Axis"); |
3871 | } | | 3866 | } |
3872 | else | | 3867 | else |
3873 | printf ("neither axis"); | | 3868 | printf ("neither axis"); |
3874 | printf ("\n"); | | 3869 | printf ("\n"); |
3875 | | | | |
3876 | if (reflection & RR_Reflect_X) printf("Setting reflection on X axis\n"); | | | |
3877 | | | | |
3878 | if (reflection & RR_Reflect_Y) printf("Setting reflection on Y axis\n"); | | | |
3879 | } | | 3870 | } |
3880 | | | 3871 | |
3881 | /* we should test configureNotify on the root window */ | | 3872 | /* we should test configureNotify on the root window */ |
3882 | XSelectInput (dpy, root, StructureNotifyMask); | | 3873 | XSelectInput (dpy, root, StructureNotifyMask); |
3883 | | | 3874 | |
3884 | if (setit && !dryrun) XRRSelectInput (dpy, root, | | 3875 | if (setit && !dryrun) XRRSelectInput (dpy, root, |
3885 | RRScreenChangeNotifyMask); | | 3876 | RRScreenChangeNotifyMask); |
3886 | if (setit && !dryrun) { | | 3877 | if (setit && !dryrun) { |
3887 | Rotation rotation = 1 << rot; | | 3878 | Rotation rotation = 1 << rot; |
3888 | status = XRRSetScreenConfigAndRate (dpy, sc, root, (SizeID) size, | | 3879 | status = XRRSetScreenConfigAndRate (dpy, sc, root, (SizeID) size, |
3889 | (Rotation) (rotation | reflection), | | 3880 | (Rotation) (rotation | reflection), |
3890 | rate, CurrentTime); | | 3881 | rate, CurrentTime); |
3891 | } | | 3882 | } |