Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenbsops.c
Go to the documentation of this file.
00001 /* -*- c-basic-offset: 8 -*- 00002 rdesktop: A Remote Desktop Protocol client. 00003 Generics backingstore operations 00004 Copyright (C) Jay Sorg 2005-2006 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License along 00017 with this program; if not, write to the Free Software Foundation, Inc., 00018 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00019 */ 00020 00021 //#include <stdlib.h> 00022 //#include <string.h> 00023 //#include "bsops.h" 00024 #include <precomp.h> 00025 00026 /* globals */ 00027 static char * g_bs = 0; 00028 static int g_bs_size = 0; 00029 00030 static int g_width1 = 800; 00031 static int g_height1 = 600; 00032 static int g_bpp = 8; 00033 static int g_Bpp = 1; 00034 00035 static int g_clip_left1 = 0; 00036 static int g_clip_top1 = 0; 00037 static int g_clip_right1 = 800; 00038 static int g_clip_bottom1 = 600; 00039 00040 /* for bs_patblt */ 00041 static char g_hatch_patterns[] = 00042 { 00043 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, /* 0 - bsHorizontal */ 00044 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 1 - bsVertical */ 00045 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, /* 2 - bsFDiagonal */ 00046 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, /* 3 - bsBDiagonal */ 00047 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08, /* 4 - bsCross */ 00048 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 /* 5 - bsDiagCross */ 00049 }; 00050 00051 00052 /*****************************************************************************/ 00053 /* do a raster op */ 00054 int 00055 bs_do_rop(int rop, int src, int dst) 00056 { 00057 switch (rop) 00058 { 00059 case 0x0: return 0; 00060 case 0x1: return ~(src | dst); 00061 case 0x2: return (~src) & dst; 00062 case 0x3: return ~src; 00063 case 0x4: return src & (~dst); 00064 case 0x5: return ~(dst); 00065 case 0x6: return src ^ dst; 00066 case 0x7: return ~(src & dst); 00067 case 0x8: return src & dst; 00068 case 0x9: return ~(src) ^ dst; 00069 case 0xa: return dst; 00070 case 0xb: return (~src) | dst; 00071 case 0xc: return src; 00072 case 0xd: return src | (~dst); 00073 case 0xe: return src | dst; 00074 case 0xf: return ~0; 00075 } 00076 return dst; 00077 } 00078 00079 /*****************************************************************************/ 00080 /* get a pixel from the in memory copy of whats on the screen */ 00081 int 00082 bs_get_pixel(int x, int y) 00083 { 00084 char * p; 00085 00086 if (x >= 0 && x < g_width1 && y >= 0 && y < g_height1) 00087 { 00088 p = g_bs + (y * g_width1 * g_Bpp) + (x * g_Bpp); 00089 if (g_Bpp == 1) 00090 { 00091 return *((unsigned char *) p); 00092 } 00093 else if (g_Bpp == 2) 00094 { 00095 return *((unsigned short *) p); 00096 } 00097 else 00098 { 00099 return *((unsigned int *) p); 00100 } 00101 } 00102 else 00103 { 00104 return 0; 00105 } 00106 } 00107 00108 /*****************************************************************************/ 00109 /* set a pixel on the screen using the clip */ 00110 void 00111 bs_set_pixel(int x, int y, int pixel, int rop, int use_clip) 00112 { 00113 char * p; 00114 00115 if (!use_clip || 00116 (x >= g_clip_left1 && x < g_clip_right1 && 00117 y >= g_clip_top1 && y < g_clip_bottom1)) 00118 { 00119 if (x >= 0 && x < g_width1 && y >= 0 && y < g_height1) 00120 { 00121 p = g_bs + (y * g_width1 * g_Bpp) + (x * g_Bpp); 00122 if (rop != 12) 00123 { 00124 pixel = bs_do_rop(rop, pixel, bs_get_pixel(x, y)); 00125 } 00126 if (g_Bpp == 1) 00127 { 00128 *((unsigned char *) p) = pixel; 00129 } 00130 else if (g_Bpp == 2) 00131 { 00132 *((unsigned short *) p) = pixel; 00133 } 00134 else 00135 { 00136 *((unsigned int *) p) = pixel; 00137 } 00138 } 00139 } 00140 } 00141 00142 /*****************************************************************************/ 00143 static char * 00144 get_bs_ptr(int x, int y) 00145 { 00146 char * p; 00147 00148 if (x >= 0 && x < g_width1 && y >= 0 && y < g_height1) 00149 { 00150 p = g_bs + (y * g_width1 * g_Bpp) + (x * g_Bpp); 00151 return p; 00152 } 00153 else 00154 { 00155 return 0; 00156 } 00157 } 00158 00159 /*****************************************************************************/ 00160 void 00161 bs_init(int width, int height, int bpp) 00162 { 00163 if (g_bs != 0) 00164 { 00165 free(g_bs); 00166 } 00167 g_width1 = width; 00168 g_height1 = height; 00169 g_bpp = bpp; 00170 g_Bpp = (bpp + 7) / 8; 00171 g_bs_size = width * height * g_Bpp; 00172 g_bs = malloc(g_bs_size); 00173 memset(g_bs, 0, g_bs_size); 00174 g_clip_left1 = 0; 00175 g_clip_top1 = 0; 00176 g_clip_right1 = width; 00177 g_clip_bottom1 = height; 00178 } 00179 00180 /*****************************************************************************/ 00181 void 00182 bs_exit(void) 00183 { 00184 if (g_bs != 0) 00185 { 00186 free(g_bs); 00187 } 00188 } 00189 00190 /*****************************************************************************/ 00191 void 00192 bs_set_clip(int x, int y, int cx, int cy) 00193 { 00194 g_clip_left1 = x; 00195 g_clip_top1 = y; 00196 g_clip_right1 = x + cx; 00197 g_clip_bottom1 = y + cy; 00198 } 00199 00200 /*****************************************************************************/ 00201 void 00202 bs_reset_clip(void) 00203 { 00204 g_clip_left1 = 0; 00205 g_clip_top1 = 0; 00206 g_clip_right1 = g_width1; 00207 g_clip_bottom1 = g_height1; 00208 } 00209 00210 /*****************************************************************************/ 00211 /* check if a certain pixel is set in a bitmap */ 00212 int 00213 bs_is_pixel_on(char * data, int x, int y, int width, int bpp) 00214 { 00215 int start; 00216 int shift; 00217 00218 if (bpp == 1) 00219 { 00220 width = (width + 7) / 8; 00221 start = (y * width) + x / 8; 00222 shift = x % 8; 00223 return (data[start] & (0x80 >> shift)) != 0; 00224 } 00225 else if (bpp == 8) 00226 { 00227 return data[y * width + x] != 0; 00228 } 00229 else if (bpp == 24) 00230 { 00231 return data[(y * 3) * width + (x * 3)] != 0 && 00232 data[(y * 3) * width + (x * 3) + 1] != 0 && 00233 data[(y * 3) * width + (x * 3) + 2] != 0; 00234 } 00235 else 00236 { 00237 return 0; 00238 } 00239 } 00240 00241 /*****************************************************************************/ 00242 void 00243 bs_set_pixel_on(char * data, int x, int y, int width, int bpp, 00244 int pixel) 00245 { 00246 int start; 00247 int shift; 00248 00249 if (bpp == 1) 00250 { 00251 width = (width + 7) / 8; 00252 start = (y * width) + x / 8; 00253 shift = x % 8; 00254 if (pixel != 0) 00255 { 00256 data[start] = data[start] | (0x80 >> shift); 00257 } 00258 else 00259 { 00260 data[start] = data[start] & ~(0x80 >> shift); 00261 } 00262 } 00263 else if (bpp == 8) 00264 { 00265 data[y * width + x] = pixel; 00266 } 00267 else if (bpp == 15 || bpp == 16) 00268 { 00269 ((unsigned short *) data)[y * width + x] = pixel; 00270 } 00271 } 00272 00273 /*****************************************************************************/ 00274 void 00275 bs_copy_mem(char * d, char * s, int n) 00276 { 00277 while (n & (~7)) 00278 { 00279 *(d++) = *(s++); 00280 *(d++) = *(s++); 00281 *(d++) = *(s++); 00282 *(d++) = *(s++); 00283 *(d++) = *(s++); 00284 *(d++) = *(s++); 00285 *(d++) = *(s++); 00286 *(d++) = *(s++); 00287 n = n - 8; 00288 } 00289 while (n > 0) 00290 { 00291 *(d++) = *(s++); 00292 n--; 00293 } 00294 } 00295 00296 /*****************************************************************************/ 00297 void 00298 bs_copy_memb(char * d, char * s, int n) 00299 { 00300 d = (d + n) - 1; 00301 s = (s + n) - 1; 00302 while (n & (~7)) 00303 { 00304 *(d--) = *(s--); 00305 *(d--) = *(s--); 00306 *(d--) = *(s--); 00307 *(d--) = *(s--); 00308 *(d--) = *(s--); 00309 *(d--) = *(s--); 00310 *(d--) = *(s--); 00311 *(d--) = *(s--); 00312 n = n - 8; 00313 } 00314 while (n > 0) 00315 { 00316 *(d--) = *(s--); 00317 n--; 00318 } 00319 } 00320 00321 /*****************************************************************************/ 00322 /* return true is the is something to draw */ 00323 int 00324 bs_warp_coords(int * x, int * y, int * cx, int * cy, 00325 int * srcx, int * srcy) 00326 { 00327 int dx; 00328 int dy; 00329 00330 if (g_clip_left1 > *x) 00331 { 00332 dx = g_clip_left1 - *x; 00333 } 00334 else 00335 { 00336 dx = 0; 00337 } 00338 if (g_clip_top1 > *y) 00339 { 00340 dy = g_clip_top1 - *y; 00341 } 00342 else 00343 { 00344 dy = 0; 00345 } 00346 if (*x + *cx > g_clip_right1) 00347 { 00348 *cx = (*cx - ((*x + *cx) - g_clip_right1)); 00349 } 00350 if (*y + *cy > g_clip_bottom1) 00351 { 00352 *cy = (*cy - ((*y + *cy) - g_clip_bottom1)); 00353 } 00354 *cx = *cx - dx; 00355 *cy = *cy - dy; 00356 if (*cx <= 0) 00357 { 00358 return 0; 00359 } 00360 if (*cy <= 0) 00361 { 00362 return 0; 00363 } 00364 *x = *x + dx; 00365 *y = *y + dy; 00366 if (srcx != 0) 00367 { 00368 *srcx = *srcx + dx; 00369 } 00370 if (srcy != 0) 00371 { 00372 *srcy = *srcy + dy; 00373 } 00374 return 1; 00375 } 00376 00377 /*****************************************************************************/ 00378 void 00379 bs_rect(int x, int y, int cx, int cy, int colour, int rop) 00380 { 00381 int i; 00382 int j; 00383 unsigned char * p8; 00384 unsigned short * p16; 00385 unsigned int * p32; 00386 00387 if (bs_warp_coords(&x, &y, &cx, &cy, 0, 0)) 00388 { 00389 if (rop == 0) /* black */ 00390 { 00391 rop = 12; 00392 colour = 0; 00393 } 00394 else if (rop == 15) /* white */ 00395 { 00396 rop = 12; 00397 colour = 0xffffff; 00398 } 00399 if (rop == 12) /* copy */ 00400 { 00401 if (g_Bpp == 1) 00402 { 00403 for (i = 0; i < cy; i++) 00404 { 00405 p8 = (unsigned char *) get_bs_ptr(x, y + i); 00406 if (p8 != 0) 00407 { 00408 for (j = 0; j < cx; j++) 00409 { 00410 *p8 = colour; 00411 p8++; 00412 } 00413 } 00414 } 00415 } 00416 else if (g_Bpp == 2) 00417 { 00418 for (i = 0; i < cy; i++) 00419 { 00420 p16 = (unsigned short *) get_bs_ptr(x, y + i); 00421 if (p16 != 0) 00422 { 00423 for (j = 0; j < cx; j++) 00424 { 00425 *p16 = colour; 00426 p16++; 00427 } 00428 } 00429 } 00430 } 00431 else 00432 { 00433 for (i = 0; i < cy; i++) 00434 { 00435 p32 = (unsigned int *) get_bs_ptr(x, y + i); 00436 if (p32 != 0) 00437 { 00438 for (j = 0; j < cx; j++) 00439 { 00440 *p32 = colour; 00441 p32++; 00442 } 00443 } 00444 } 00445 } 00446 } 00447 else /* slow */ 00448 { 00449 for (i = 0; i < cy; i++) 00450 { 00451 for (j = 0; j < cx; j++) 00452 { 00453 bs_set_pixel(j + x, i + y, colour, rop, 0); 00454 } 00455 } 00456 } 00457 } 00458 } 00459 00460 /*****************************************************************************/ 00461 void 00462 bs_screenblt(int rop, int x, int y, int cx, int cy, 00463 int srcx, int srcy) 00464 { 00465 int p; 00466 int i; 00467 int j; 00468 char * src; 00469 char * dst; 00470 00471 if (bs_warp_coords(&x, &y, &cx, &cy, &srcx, &srcy)) 00472 { 00473 if (rop == 12) /* copy */ 00474 { 00475 if (srcy < y) /* copy down - bottom to top */ 00476 { 00477 for (i = cy - 1; i >= 0; i--) 00478 { 00479 src = get_bs_ptr(srcx, srcy + i); 00480 dst = get_bs_ptr(x, y + i); 00481 if (src != 0 && dst != 0) 00482 { 00483 bs_copy_mem(dst, src, cx * g_Bpp); 00484 } 00485 } 00486 } 00487 else if (srcy > y || srcx > x) /* copy up or left - top to bottom */ 00488 { 00489 for (i = 0; i < cy; i++) 00490 { 00491 src = get_bs_ptr(srcx, srcy + i); 00492 dst = get_bs_ptr(x, y + i); 00493 if (src != 0 && dst != 0) 00494 { 00495 bs_copy_mem(dst, src, cx * g_Bpp); 00496 } 00497 } 00498 } 00499 else /* copy straight right */ 00500 { 00501 for (i = 0; i < cy; i++) 00502 { 00503 src = get_bs_ptr(srcx, srcy + i); 00504 dst = get_bs_ptr(x, y + i); 00505 if (src != 0 && dst != 0) 00506 { 00507 bs_copy_memb(dst, src, cx * g_Bpp); 00508 } 00509 } 00510 } 00511 } 00512 else /* slow */ 00513 { 00514 if (srcy < y) /* copy down - bottom to top */ 00515 { 00516 for (i = cy - 1; i >= 0; i--) 00517 { 00518 for (j = 0; j < cx; j++) 00519 { 00520 p = bs_get_pixel(srcx + j, srcy + i); 00521 bs_set_pixel(x + j, y + i, p, rop, 0); 00522 } 00523 } 00524 } 00525 else if (srcy > y || srcx > x) /* copy up or left - top to bottom */ 00526 { 00527 for (i = 0; i < cy; i++) 00528 { 00529 for (j = 0; j < cx; j++) 00530 { 00531 p = bs_get_pixel(srcx + j, srcy + i); 00532 bs_set_pixel(x + j, y + i, p, rop, 0); 00533 } 00534 } 00535 } 00536 else /* copy straight right */ 00537 { 00538 for (i = 0; i < cy; i++) 00539 { 00540 for (j = cx - 1; j >= 0; j--) 00541 { 00542 p = bs_get_pixel(srcx + j, srcy + i); 00543 bs_set_pixel(x + j, y + i, p, rop, 0); 00544 } 00545 } 00546 } 00547 } 00548 } 00549 } 00550 00551 /*****************************************************************************/ 00552 void 00553 bs_memblt(int opcode, int x, int y, int cx, int cy, 00554 void * srcdata, int srcwidth, int srcheight, 00555 int srcx, int srcy) 00556 { 00557 int i; 00558 int j; 00559 int p; 00560 char * dst; 00561 char * src; 00562 00563 if (bs_warp_coords(&x, &y, &cx, &cy, &srcx, &srcy)) 00564 { 00565 if (opcode == 12) /* copy */ 00566 { 00567 if (g_Bpp == 1) 00568 { 00569 src = (char *) (((unsigned char *) srcdata) + srcy * srcwidth + srcx); 00570 } 00571 else if (g_Bpp == 2) 00572 { 00573 src = (char *) (((unsigned short *) srcdata) + srcy * srcwidth + srcx); 00574 } 00575 else 00576 { 00577 src = (char *) (((unsigned int *) srcdata) + srcy * srcwidth + srcx); 00578 } 00579 for (i = 0; i < cy; i++) 00580 { 00581 dst = get_bs_ptr(x, y + i); 00582 if (dst != 0) 00583 { 00584 bs_copy_mem(dst, src, cx * g_Bpp); 00585 src += srcwidth * g_Bpp; 00586 } 00587 } 00588 } 00589 else /* slow */ 00590 { 00591 if (g_Bpp == 1) 00592 { 00593 for (i = 0; i < cy; i++) 00594 { 00595 for (j = 0; j < cx; j++) 00596 { 00597 p = *(((unsigned char *) srcdata) + 00598 ((i + srcy) * srcwidth + (j + srcx))); 00599 bs_set_pixel(x + j, y + i, p, opcode, 0); 00600 } 00601 } 00602 } 00603 else if (g_Bpp == 2) 00604 { 00605 for (i = 0; i < cy; i++) 00606 { 00607 for (j = 0; j < cx; j++) 00608 { 00609 p = *(((unsigned short *) srcdata) + 00610 ((i + srcy) * srcwidth + (j + srcx))); 00611 bs_set_pixel(x + j, y + i, p, opcode, 0); 00612 } 00613 } 00614 } 00615 else 00616 { 00617 for (i = 0; i < cy; i++) 00618 { 00619 for (j = 0; j < cx; j++) 00620 { 00621 p = *(((unsigned int *) srcdata) + 00622 ((i + srcy) * srcwidth + (j + srcx))); 00623 bs_set_pixel(x + j, y + i, p, opcode, 0); 00624 } 00625 } 00626 } 00627 } 00628 } 00629 } 00630 00631 /*****************************************************************************/ 00632 void 00633 bs_draw_glyph(int x, int y, char * glyph_data, int glyph_width, 00634 int glyph_height, int fgcolour) 00635 { 00636 int i; 00637 int j; 00638 00639 for (i = 0; i < glyph_height; i++) 00640 { 00641 for (j = 0; j < glyph_width; j++) 00642 { 00643 if (bs_is_pixel_on(glyph_data, j, i, glyph_width, 8)) 00644 { 00645 bs_set_pixel(x + j, y + i, fgcolour, 12, 1); 00646 } 00647 } 00648 } 00649 } 00650 00651 /*****************************************************************************/ 00652 /* Bresenham's line drawing algorithm */ 00653 void 00654 bs_line(int opcode, int startx, int starty, int endx, int endy, 00655 int pen_width, int pen_style, int pen_colour) 00656 { 00657 int dx; 00658 int dy; 00659 int incx; 00660 int incy; 00661 int dpr; 00662 int dpru; 00663 int p; 00664 00665 if (startx > endx) 00666 { 00667 dx = startx - endx; 00668 incx = -1; 00669 } 00670 else 00671 { 00672 dx = endx - startx; 00673 incx = 1; 00674 } 00675 if (starty > endy) 00676 { 00677 dy = starty - endy; 00678 incy = -1; 00679 } 00680 else 00681 { 00682 dy = endy - starty; 00683 incy = 1; 00684 } 00685 if (dx >= dy) 00686 { 00687 dpr = dy << 1; 00688 dpru = dpr - (dx << 1); 00689 p = dpr - dx; 00690 for (; dx >= 0; dx--) 00691 { 00692 if (startx != endx || starty != endy) 00693 { 00694 bs_set_pixel(startx, starty, pen_colour, opcode, 1); 00695 } 00696 if (p > 0) 00697 { 00698 startx += incx; 00699 starty += incy; 00700 p += dpru; 00701 } 00702 else 00703 { 00704 startx += incx; 00705 p += dpr; 00706 } 00707 } 00708 } 00709 else 00710 { 00711 dpr = dx << 1; 00712 dpru = dpr - (dy << 1); 00713 p = dpr - dy; 00714 for (; dy >= 0; dy--) 00715 { 00716 if (startx != endx || starty != endy) 00717 { 00718 bs_set_pixel(startx, starty, pen_colour, opcode, 1); 00719 } 00720 if (p > 0) 00721 { 00722 startx += incx; 00723 starty += incy; 00724 p += dpru; 00725 } 00726 else 00727 { 00728 starty += incy; 00729 p += dpr; 00730 } 00731 } 00732 } 00733 } 00734 00735 /*****************************************************************************/ 00736 void 00737 bs_patblt(int opcode, int x, int y, int cx, int cy, 00738 int brush_style, char * brush_pattern, 00739 int brush_x_org, int brush_y_org, 00740 int bgcolour, int fgcolour) 00741 { 00742 int i; 00743 int j; 00744 char ipattern[8]; 00745 char * b; 00746 00747 b = 0; 00748 switch (brush_style) 00749 { 00750 case 0: 00751 bs_rect(x, y, cx, cy, fgcolour, opcode); 00752 break; 00753 case 2: /* Hatch */ 00754 b = g_hatch_patterns + brush_pattern[0] * 8; 00755 break; 00756 case 3: 00757 for (i = 0; i < 8; i++) 00758 { 00759 ipattern[i] = ~brush_pattern[7 - i]; 00760 } 00761 b = ipattern; 00762 break; 00763 } 00764 if (b != 0) 00765 { 00766 for (i = 0; i < cy; i++) 00767 { 00768 for (j = 0; j < cx; j++) 00769 { 00770 if (bs_is_pixel_on(b, (x + j + brush_x_org) % 8, 00771 (y + i + brush_y_org) % 8, 8, 1)) 00772 { 00773 bs_set_pixel(x + j, y + i, fgcolour, opcode, 1); 00774 } 00775 else 00776 { 00777 bs_set_pixel(x + j, y + i, bgcolour, opcode, 1); 00778 } 00779 } 00780 } 00781 } 00782 } 00783 00784 /*****************************************************************************/ 00785 void 00786 bs_copy_box(char * dst, int x, int y, int cx, int cy, int line_size) 00787 { 00788 char * src; 00789 int i; 00790 00791 /* shouldn't happen */ 00792 if (cx < 1 || cy < 1) 00793 { 00794 return; 00795 } 00796 /* nothing to draw, memset and leave */ 00797 if (x + cx < 0 || y + cy < 0 || x >= g_width1 || y >= g_height1) 00798 { 00799 memset(dst, 0, cx * cy * g_Bpp); 00800 return; 00801 } 00802 /* check if it goes over an edge */ 00803 if (x < 0 || y < 0 || x + cx > g_width1 || y + cy > g_height1) 00804 { 00805 memset(dst, 0, cx * cy * g_Bpp); 00806 if (x < 0) 00807 { 00808 cx += x; 00809 dst += -x * g_Bpp; 00810 x = 0; 00811 } 00812 if (x + cx > g_width1) 00813 { 00814 cx = g_width1 - x; 00815 } 00816 for (i = 0; i < cy; i++) 00817 { 00818 src = get_bs_ptr(x, y + i); 00819 if (src != 0) 00820 { 00821 bs_copy_mem(dst, src, cx * g_Bpp); 00822 } 00823 dst += line_size; 00824 } 00825 } 00826 else /* whole box is within */ 00827 { 00828 for (i = 0; i < cy; i++) 00829 { 00830 src = get_bs_ptr(x, y + i); 00831 if (src != 0) 00832 { 00833 bs_copy_mem(dst, src, cx * g_Bpp); 00834 } 00835 dst += line_size; 00836 } 00837 } 00838 } 00839 Generated on Sun May 27 2012 04:17:09 for ReactOS by
1.7.6.1
|