00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "TGWin32.h"
00025 #include <stdio.h>
00026 #include <string.h>
00027 #include <stdlib.h>
00028 #include <ctype.h>
00029 #include <process.h>
00030 #include <wchar.h>
00031 #include "gdk/gdkkeysyms.h"
00032 #include "xatom.h"
00033 #include <winuser.h>
00034
00035 #include "TROOT.h"
00036 #include "TApplication.h"
00037 #include "TColor.h"
00038 #include "TPoint.h"
00039 #include "TMath.h"
00040 #include "TStorage.h"
00041 #include "TStyle.h"
00042 #include "TSystem.h"
00043 #include "TGFrame.h"
00044 #include "TError.h"
00045 #include "TException.h"
00046 #include "TClassTable.h"
00047 #include "KeySymbols.h"
00048 #include "TWinNTSystem.h"
00049 #include "TGWin32VirtualXProxy.h"
00050 #include "TGWin32InterpreterProxy.h"
00051 #include "TWin32SplashThread.h"
00052 #include "TString.h"
00053 #include "TObjString.h"
00054 #include "TObjArray.h"
00055 #include "TExMap.h"
00056 #include "TEnv.h"
00057 #include "RStipples.h"
00058 #include "TEnv.h"
00059
00060
00061 #define XDND_PROTOCOL_VERSION 5
00062 #ifndef IDC_HAND
00063 #define IDC_HAND MAKEINTRESOURCE(32649)
00064 #endif
00065
00066 extern "C" {
00067 void gdk_win32_draw_rectangle (GdkDrawable *drawable,
00068 GdkGC *gc,
00069 gint filled,
00070 gint x,
00071 gint y,
00072 gint width,
00073 gint height);
00074 void gdk_win32_draw_arc (GdkDrawable *drawable,
00075 GdkGC *gc,
00076 gint filled,
00077 gint x,
00078 gint y,
00079 gint width,
00080 gint height,
00081 gint angle1,
00082 gint angle2);
00083 void gdk_win32_draw_polygon (GdkDrawable *drawable,
00084 GdkGC *gc,
00085 gint filled,
00086 GdkPoint *points,
00087 gint npoints);
00088 void gdk_win32_draw_text (GdkDrawable *drawable,
00089 GdkFont *font,
00090 GdkGC *gc,
00091 gint x,
00092 gint y,
00093 const gchar *text,
00094 gint text_length);
00095 void gdk_win32_draw_points (GdkDrawable *drawable,
00096 GdkGC *gc,
00097 GdkPoint *points,
00098 gint npoints);
00099 void gdk_win32_draw_segments (GdkDrawable *drawable,
00100 GdkGC *gc,
00101 GdkSegment *segs,
00102 gint nsegs);
00103 void gdk_win32_draw_lines (GdkDrawable *drawable,
00104 GdkGC *gc,
00105 GdkPoint *points,
00106 gint npoints);
00107
00108 };
00109
00110
00111
00112 struct XWindow_t {
00113 Int_t open;
00114 Int_t double_buffer;
00115 Int_t ispixmap;
00116 GdkDrawable *drawing;
00117 GdkDrawable *window;
00118 GdkDrawable *buffer;
00119 UInt_t width;
00120 UInt_t height;
00121 Int_t clip;
00122 Int_t xclip;
00123 Int_t yclip;
00124 UInt_t wclip;
00125 UInt_t hclip;
00126 ULong_t *new_colors;
00127 Int_t ncolors;
00128 };
00129
00130
00131
00132 int gdk_debug_level;
00133
00134 namespace {
00135
00136
00137 GdkAtom gClipboardAtom = GDK_NONE;
00138 static XWindow_t *gCws;
00139 static XWindow_t *gTws;
00140
00141
00142
00143
00144
00145
00146 const Int_t kBIGGEST_RGB_VALUE = 65535;
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 const int kMAXGC = 7;
00157 static GdkGC *gGClist[kMAXGC];
00158 static GdkGC *gGCline;
00159 static GdkGC *gGCmark;
00160 static GdkGC *gGCfill;
00161 static GdkGC *gGCtext;
00162 static GdkGC *gGCinvt;
00163 static GdkGC *gGCdash;
00164 static GdkGC *gGCpxmp;
00165
00166 static GdkGC *gGCecho;
00167
00168 static Int_t gFillHollow;
00169 static GdkPixmap *gFillPattern;
00170
00171
00172
00173
00174 static char *gTextFont = "arial.ttf";
00175
00176
00177
00178
00179 const Int_t kMAXMK = 100;
00180 static struct {
00181 int type;
00182 int n;
00183 GdkPoint xy[kMAXMK];
00184 } gMarker;
00185
00186
00187
00188
00189 static int gLineStyle = GDK_LINE_SOLID;
00190 static int gCapStyle = GDK_CAP_BUTT;
00191 static int gJoinStyle = GDK_JOIN_MITER;
00192 static char gDashList[10];
00193 static int gDashLength = 0;
00194 static int gDashOffset = 0;
00195 static int gDashSize = 0;
00196
00197
00198
00199
00200 static ULong_t gMouseMask =
00201 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK
00202 | GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK | GDK_KEY_PRESS_MASK
00203 | GDK_KEY_RELEASE_MASK;
00204 static ULong_t gKeybdMask =
00205 GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK | GDK_ENTER_NOTIFY_MASK |
00206 GDK_LEAVE_NOTIFY_MASK;
00207
00208
00209
00210
00211 const char null_cursor_bits[] = {
00212 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00213 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00214 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
00215 };
00216 static GdkCursor *gNullCursor;
00217
00218 static bool gdk_initialized = false;
00219
00220
00221
00222 struct MWMHintsProperty_t {
00223 Handle_t fFlags;
00224 Handle_t fFunctions;
00225 Handle_t fDecorations;
00226 Int_t fInputMode;
00227 };
00228
00229
00230
00231 const ULong_t kMWMHintsFunctions = BIT(0);
00232 const ULong_t kMWMHintsDecorations = BIT(1);
00233 const ULong_t kMWMHintsInputMode = BIT(2);
00234
00235 const Int_t kPropMotifWMHintsElements = 4;
00236 const Int_t kPropMWMHintElements = kPropMotifWMHintsElements;
00237
00238
00239
00240
00241 struct KeySymbolMap_t {
00242 KeySym fXKeySym;
00243 EKeySym fKeySym;
00244 };
00245
00246 static char *keyCodeToString[] = {
00247 "",
00248 "",
00249 "",
00250 "",
00251 "",
00252 "",
00253 "",
00254 "",
00255 "\015",
00256 "\t",
00257 "",
00258 "",
00259 "",
00260 "\r",
00261 "",
00262 "",
00263 "",
00264 "",
00265 "",
00266 "",
00267 "",
00268 "",
00269 "",
00270 "",
00271 "",
00272 "",
00273 "",
00274 "",
00275 "",
00276 "",
00277 "",
00278 "",
00279 " ",
00280 "",
00281 "",
00282 "",
00283 "",
00284 "",
00285 "",
00286 "",
00287 "",
00288 "",
00289 "",
00290 "",
00291 "",
00292 "",
00293 "\037",
00294 "",
00295 };
00296
00297
00298
00299
00300 static KeySymbolMap_t gKeyMap[] = {
00301 {GDK_Escape, kKey_Escape},
00302 {GDK_Tab, kKey_Tab},
00303 #ifndef GDK_ISO_Left_Tab
00304 {0xFE20, kKey_Backtab},
00305 #else
00306 {GDK_ISO_Left_Tab, kKey_Backtab},
00307 #endif
00308 {GDK_BackSpace, kKey_Backspace},
00309 {GDK_Return, kKey_Return},
00310 {GDK_Insert, kKey_Insert},
00311 {GDK_Delete, kKey_Delete},
00312 {GDK_Clear, kKey_Delete},
00313 {GDK_Pause, kKey_Pause},
00314 {GDK_Print, kKey_Print},
00315 {0x1005FF60, kKey_SysReq},
00316 {0x1007ff00, kKey_SysReq},
00317 {GDK_Home, kKey_Home},
00318 {GDK_End, kKey_End},
00319 {GDK_Left, kKey_Left},
00320 {GDK_Up, kKey_Up},
00321 {GDK_Right, kKey_Right},
00322 {GDK_Down, kKey_Down},
00323 {GDK_Prior, kKey_Prior},
00324 {GDK_Next, kKey_Next},
00325 {GDK_Shift_L, kKey_Shift},
00326 {GDK_Shift_R, kKey_Shift},
00327 {GDK_Shift_Lock, kKey_Shift},
00328 {GDK_Control_L, kKey_Control},
00329 {GDK_Control_R, kKey_Control},
00330 {GDK_Meta_L, kKey_Meta},
00331 {GDK_Meta_R, kKey_Meta},
00332 {GDK_Alt_L, kKey_Alt},
00333 {GDK_Alt_R, kKey_Alt},
00334 {GDK_Caps_Lock, kKey_CapsLock},
00335 {GDK_Num_Lock, kKey_NumLock},
00336 {GDK_Scroll_Lock, kKey_ScrollLock},
00337 {GDK_KP_Space, kKey_Space},
00338 {GDK_KP_Tab, kKey_Tab},
00339 {GDK_KP_Enter, kKey_Enter},
00340 {GDK_KP_Equal, kKey_Equal},
00341 {GDK_KP_Multiply, kKey_Asterisk},
00342 {GDK_KP_Add, kKey_Plus},
00343 {GDK_KP_Separator, kKey_Comma},
00344 {GDK_KP_Subtract, kKey_Minus},
00345 {GDK_KP_Decimal, kKey_Period},
00346 {GDK_KP_Divide, kKey_Slash},
00347 {0, (EKeySym) 0}
00348 };
00349
00350
00351
00352
00353 static Int_t _lookup_string(Event_t * event, char *buf, Int_t buflen)
00354 {
00355 int i;
00356 int n = event->fUser[1];
00357 if (n > 0) {
00358 for (i = 0; i < n; i++) {
00359 buf[i] = event->fUser[2 + i];
00360 }
00361 buf[n] = 0;
00362 } else {
00363 buf[0] = 0;
00364 }
00365 if (event->fCode <= 0x20) {
00366 strncpy(buf, keyCodeToString[event->fCode], buflen - 1);
00367 }
00368 return n;
00369 }
00370
00371
00372 inline void SplitLong(Long_t ll, Long_t & i1, Long_t & i2)
00373 {
00374 union {
00375 Long_t l;
00376 Int_t i[2];
00377 } conv;
00378
00379 conv.l = 0L;
00380 conv.i[0] = 0;
00381 conv.i[1] = 0;
00382
00383 conv.l = ll;
00384 i1 = conv.i[0];
00385 i2 = conv.i[1];
00386 }
00387
00388
00389 inline void AsmLong(Long_t i1, Long_t i2, Long_t & ll)
00390 {
00391 union {
00392 Long_t l;
00393 Int_t i[2];
00394 } conv;
00395
00396 conv.i[0] = (Int_t) i1;
00397 conv.i[1] = (Int_t) i2;
00398 ll = conv.l;
00399 }
00400
00401
00402 static BOOL CALLBACK EnumChildProc(HWND hwndChild, LPARAM lParam)
00403 {
00404
00405
00406 ::ShowWindow(hwndChild, SW_SHOWNORMAL);
00407 GdkWindow *child = gdk_window_lookup(hwndChild);
00408 if (child)
00409 ((GdkWindowPrivate *) child)->mapped = TRUE;
00410 return TRUE;
00411 }
00412
00413
00414 static void _ChangeProperty(HWND w, char *np, char *dp, int n, Atom_t type)
00415 {
00416 HGLOBAL hMem;
00417 char *p;
00418
00419 hMem = ::GetProp(w, np);
00420 if (hMem != NULL) {
00421 ::GlobalFree(hMem);
00422 }
00423 hMem = ::GlobalAlloc(GHND, n + sizeof(Atom_t));
00424 p = (char *) ::GlobalLock(hMem);
00425 memcpy(p, &type, sizeof(Atom_t));
00426 memcpy(p + sizeof(Atom_t), dp, n);
00427 ::GlobalUnlock(hMem);
00428 ::SetProp(w, np, hMem);
00429 ::GlobalFree(hMem);
00430 }
00431
00432
00433 static void W32ChangeProperty(HWND w, Atom_t property, Atom_t type,
00434 int format, int mode, const unsigned char *data,
00435 int nelements)
00436 {
00437
00438
00439 char *atomName;
00440 char buffer[256];
00441 char *p, *s;
00442 int len;
00443 char propName[32];
00444
00445 if (mode == GDK_PROP_MODE_REPLACE || mode == GDK_PROP_MODE_PREPEND) {
00446 len = (int) ::GlobalGetAtomName(property, buffer, sizeof(buffer));
00447 if ((atomName = (char *) malloc(len + 1)) == NULL) {
00448 return;
00449 } else {
00450 strcpy(atomName, buffer);
00451 }
00452 sprintf(propName, "#0x%0.4x", atomName);
00453 _ChangeProperty(w, propName, (char *) data, nelements, type);
00454 free(atomName);
00455 }
00456 }
00457
00458
00459 static int _GetWindowProperty(GdkWindow * id, Atom_t property, Long_t long_offset,
00460 Long_t long_length, Bool_t delete_it, Atom_t req_type,
00461 Atom_t * actual_type_return,
00462 Int_t * actual_format_return, ULong_t * nitems_return,
00463 ULong_t * bytes_after_return, UChar_t ** prop_return)
00464 {
00465
00466
00467 if (!id) return 0;
00468
00469 char *atomName;
00470 char *data, *destPtr;
00471 char propName[32];
00472 HGLOBAL handle;
00473 HGLOBAL hMem;
00474 HWND w;
00475
00476 w = (HWND) GDK_DRAWABLE_XID(id);
00477
00478 if (::IsClipboardFormatAvailable(CF_TEXT) && ::OpenClipboard(NULL)) {
00479 handle = ::GetClipboardData(CF_TEXT);
00480 if (handle != NULL) {
00481 data = (char *) ::GlobalLock(handle);
00482 *nitems_return = strlen(data);
00483 *prop_return = (UChar_t *) malloc(*nitems_return + 1);
00484 destPtr = (char *) *prop_return;
00485 while (*data != '\0') {
00486 if (*data != '\r') {
00487 *destPtr = *data;
00488 destPtr++;
00489 }
00490 data++;
00491 }
00492 *destPtr = '\0';
00493 ::GlobalUnlock(handle);
00494 *actual_type_return = XA_STRING;
00495 *bytes_after_return = 0;
00496 }
00497 ::CloseClipboard();
00498 return 1;
00499 }
00500 if (delete_it) {
00501 ::RemoveProp(w, propName);
00502 }
00503 return 1;
00504 }
00505
00506
00507 static ULong_t GetPixelImage(Drawable_t id, Int_t x, Int_t y)
00508 {
00509
00510
00511 if (!id) return 0;
00512
00513 GdkImage *image = (GdkImage *)id;
00514 ULong_t pixel;
00515
00516 if (image->depth == 1) {
00517 pixel = (((char *) image->mem)[y * image->bpl + (x >> 3)] & (1 << (7 - (x & 0x7)))) != 0;
00518 } else {
00519 UChar_t *pixelp = (UChar_t *) image->mem + y * image->bpl + x * image->bpp;
00520 switch (image->bpp) {
00521 case 1:
00522 pixel = *pixelp;
00523 break;
00524
00525 case 2:
00526 pixel = pixelp[0] | (pixelp[1] << 8);
00527 break;
00528 case 3:
00529 pixel = pixelp[0] | (pixelp[1] << 8) | (pixelp[2] << 16);
00530 break;
00531 case 4:
00532 pixel = pixelp[0] | (pixelp[1] << 8) | (pixelp[2] << 16);
00533 break;
00534 }
00535 }
00536 return pixel;
00537 }
00538
00539
00540 static void CollectImageColors(ULong_t pixel, ULong_t * &orgcolors,
00541 Int_t & ncolors, Int_t & maxcolors)
00542 {
00543
00544
00545 if (maxcolors == 0) {
00546 ncolors = 0;
00547 maxcolors = 100;
00548 orgcolors = (ULong_t*) ::operator new(maxcolors*sizeof(ULong_t));
00549 }
00550
00551 for (int i = 0; i < ncolors; i++) {
00552 if (pixel == orgcolors[i]) return;
00553 }
00554 if (ncolors >= maxcolors) {
00555 orgcolors = (ULong_t *) TStorage::ReAlloc(orgcolors,
00556 maxcolors * 2 *
00557 sizeof(ULong_t),
00558 maxcolors *
00559 sizeof(ULong_t));
00560 maxcolors *= 2;
00561 }
00562 orgcolors[ncolors++] = pixel;
00563 }
00564
00565
00566 static char *EventMask2String(UInt_t evmask)
00567 {
00568
00569
00570 static char bfr[500];
00571 char *p = bfr;
00572
00573 *p = '\0';
00574 #define BITmask(x) \
00575 if (evmask & k##x##Mask) \
00576 p += sprintf (p, "%s" #x, (p > bfr ? " " : ""))
00577 BITmask(Exposure);
00578 BITmask(PointerMotion);
00579 BITmask(ButtonMotion);
00580 BITmask(ButtonPress);
00581 BITmask(ButtonRelease);
00582 BITmask(KeyPress);
00583 BITmask(KeyRelease);
00584 BITmask(EnterWindow);
00585 BITmask(LeaveWindow);
00586 BITmask(FocusChange);
00587 BITmask(StructureNotify);
00588 #undef BITmask
00589
00590 return bfr;
00591 }
00592
00593
00594 class TGWin32MainThread {
00595
00596 public:
00597 void *fHandle;
00598 DWORD fId;
00599 static LPCRITICAL_SECTION fCritSec;
00600 static LPCRITICAL_SECTION fMessageMutex;
00601
00602 TGWin32MainThread();
00603 ~TGWin32MainThread();
00604 static void LockMSG();
00605 static void UnlockMSG();
00606 };
00607
00608 TGWin32MainThread *gMainThread = 0;
00609 LPCRITICAL_SECTION TGWin32MainThread::fCritSec = 0;
00610 LPCRITICAL_SECTION TGWin32MainThread::fMessageMutex = 0;
00611
00612
00613
00614 TGWin32MainThread::~TGWin32MainThread()
00615 {
00616
00617
00618 if (fCritSec) {
00619 ::LeaveCriticalSection(fCritSec);
00620 ::DeleteCriticalSection(fCritSec);
00621 delete fCritSec;
00622 }
00623 fCritSec = 0;
00624
00625 if (fMessageMutex) {
00626 ::LeaveCriticalSection(fMessageMutex);
00627 ::DeleteCriticalSection(fMessageMutex);
00628 delete fMessageMutex;
00629 }
00630 fMessageMutex = 0;
00631
00632 if(fHandle) {
00633 ::PostThreadMessage(fId, WM_QUIT, 0, 0);
00634 ::CloseHandle(fHandle);
00635 }
00636 fHandle = 0;
00637 }
00638
00639
00640 void TGWin32MainThread::LockMSG()
00641 {
00642
00643
00644 if (fMessageMutex) ::EnterCriticalSection(fMessageMutex);
00645 }
00646
00647
00648 void TGWin32MainThread::UnlockMSG()
00649 {
00650
00651
00652 if (fMessageMutex) ::LeaveCriticalSection(fMessageMutex);
00653 }
00654
00655
00656 class TGWin32RefreshTimer : public TTimer {
00657
00658 public:
00659 TGWin32RefreshTimer() : TTimer(10, kTRUE) { if (gSystem) gSystem->AddTimer(this); }
00660 ~TGWin32RefreshTimer() { if (gSystem) gSystem->RemoveTimer(this); }
00661 Bool_t Notify()
00662 {
00663 Reset();
00664 MSG msg;
00665
00666 while (::PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE)) {
00667 ::PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE);
00668 if (!gVirtualX)
00669 Sleep(200);
00670 if (gVirtualX)
00671 ((TGWin32*)gVirtualX)->GUIThreadMessageFunc(&msg);
00672 }
00673 return kFALSE;
00674 }
00675 };
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720 Bool_t GUIThreadMessageWrapper(MSG* msg)
00721 {
00722
00723
00724
00725
00726 return ((TGWin32*)gVirtualX)->GUIThreadMessageFunc(msg);
00727 }
00728
00729
00730 TGWin32MainThread::TGWin32MainThread()
00731 {
00732
00733
00734 fCritSec = new CRITICAL_SECTION;
00735 ::InitializeCriticalSection(fCritSec);
00736 fMessageMutex = new CRITICAL_SECTION;
00737 ::InitializeCriticalSection(fMessageMutex);
00738 fHandle = ((TWinNTSystem*)gSystem)->GetGUIThreadHandle();
00739 fId = ((TWinNTSystem*)gSystem)->GetGUIThreadId();
00740 ((TWinNTSystem*)gSystem)->SetGUIThreadMsgHandler(GUIThreadMessageWrapper);
00741 }
00742
00743 }
00744
00745
00746 ClassImp(TGWin32)
00747
00748
00749 TGWin32::TGWin32(): fRefreshTimer(0)
00750 {
00751
00752
00753 fScreenNumber = 0;
00754 fWindows = 0;
00755 fColors = 0;
00756 }
00757
00758
00759 TGWin32::TGWin32(const char *name, const char *title) : TVirtualX(name,title), fRefreshTimer(0)
00760 {
00761
00762
00763 fScreenNumber = 0;
00764 fHasTTFonts = kFALSE;
00765 fUseSysPointers = kFALSE;
00766 fTextAlignH = 1;
00767 fTextAlignV = 1;
00768 fTextAlign = 7;
00769 fTextMagnitude = 1;
00770 fCharacterUpX = 1;
00771 fCharacterUpY = 1;
00772 fDrawMode = kCopy;
00773 fWindows = 0;
00774 fMaxNumberOfWindows = 10;
00775 fXEvent = 0;
00776 fFillColorModified = kFALSE;
00777 fFillStyleModified = kFALSE;
00778 fLineColorModified = kFALSE;
00779 fPenModified = kFALSE;
00780 fMarkerStyleModified = kFALSE;
00781 fMarkerColorModified = kFALSE;
00782
00783 fWindows = (XWindow_t*) TStorage::Alloc(fMaxNumberOfWindows*sizeof(XWindow_t));
00784 for (int i = 0; i < fMaxNumberOfWindows; i++) fWindows[i].open = 0;
00785
00786 fColors = new TExMap;
00787
00788 if (gApplication) {
00789 TString arg = gSystem->BaseName(gApplication->Argv(0));
00790 if (!arg.Contains("PVSS"))
00791 fRefreshTimer = new TGWin32RefreshTimer();
00792 } else {
00793 fRefreshTimer = new TGWin32RefreshTimer();
00794 }
00795
00796
00797 if (!gROOT->IsBatch() && !gMainThread) {
00798 gMainThread = new TGWin32MainThread();
00799 TGWin32ProxyBase::fgMainThreadId = ::GetCurrentThreadId();
00800 TGWin32VirtualXProxy::fgRealObject = this;
00801 gPtr2VirtualX = &TGWin32VirtualXProxy::ProxyObject;
00802 gPtr2Interpreter = &TGWin32InterpreterProxy::ProxyObject;
00803 }
00804 }
00805
00806
00807 TGWin32::~TGWin32()
00808 {
00809
00810
00811 CloseDisplay();
00812 if (fRefreshTimer)
00813 delete fRefreshTimer;
00814 if (!fColors) return;
00815 Long64_t key, value;
00816 TExMapIter it(fColors);
00817 while (it.Next(key, value)) {
00818 XColor_t *col = (XColor_t *) value;
00819 delete col;
00820 }
00821 delete fColors;
00822 }
00823
00824
00825 VOID CALLBACK MyTimerProc(HWND hwnd, UINT message, UINT idTimer, DWORD dwTime)
00826 {
00827
00828
00829 gSystem->ProcessEvents();
00830
00831 }
00832
00833
00834 Bool_t TGWin32::GUIThreadMessageFunc(MSG* msg)
00835 {
00836
00837
00838
00839
00840 Bool_t ret = kFALSE;
00841 static Int_t m_timer = 0;
00842
00843 if ( (msg->message == WM_NCLBUTTONDOWN) ) {
00844 if (m_timer == 0)
00845 m_timer = SetTimer(NULL, 1, 20, (TIMERPROC) MyTimerProc);
00846 }
00847 else if (msg->message == WM_NCMOUSELEAVE ) {
00848 if (m_timer) {
00849 KillTimer(NULL, m_timer);
00850 }
00851 m_timer = 0;
00852 }
00853
00854 if (msg->message == TGWin32ProxyBase::fgPostMessageId) {
00855 if (msg->wParam) {
00856 TGWin32ProxyBase *proxy = (TGWin32ProxyBase*)msg->wParam;
00857 proxy->ExecuteCallBack(kTRUE);
00858 } else {
00859 ret = kTRUE;
00860 }
00861 } else if (msg->message == TGWin32ProxyBase::fgPingMessageId) {
00862 TGWin32ProxyBase::GlobalUnlock();
00863 } else {
00864
00865
00866
00867
00868 TGWin32MainThread::LockMSG();
00869 TranslateMessage(msg);
00870 DispatchMessage(msg);
00871 TGWin32MainThread::UnlockMSG();
00872 }
00873 return ret;
00874 }
00875
00876
00877 Bool_t TGWin32::IsCmdThread() const
00878 {
00879
00880
00881 return ((::GetCurrentThreadId() == TGWin32ProxyBase::fgMainThreadId) ||
00882 (::GetCurrentThreadId() == TGWin32ProxyBase::fgUserThreadId));
00883 }
00884
00885
00886 void TGWin32::CloseDisplay()
00887 {
00888
00889
00890
00891 TGWin32ProxyBase::GlobalLock();
00892
00893
00894 gPtr2VirtualX = 0;
00895 gPtr2Interpreter = 0;
00896 gVirtualX = TGWin32VirtualXProxy::RealObject();
00897 gInterpreter = TGWin32InterpreterProxy::RealObject();
00898
00899
00900
00901 TGWin32MainThread *delThread = gMainThread;
00902 if (gMainThread) {
00903 gMainThread = 0;
00904 delete delThread;
00905 }
00906
00907 TGWin32ProxyBase::fgMainThreadId = 0;
00908
00909
00910 TWin32SplashThread *delSplash = gSplash;
00911 if (gSplash) {
00912 gSplash = 0;
00913 delete delSplash;
00914 }
00915
00916 if (fWindows) TStorage::Dealloc(fWindows);
00917 fWindows = 0;
00918
00919 if (fXEvent) gdk_event_free((GdkEvent*)fXEvent);
00920
00921 TGWin32ProxyBase::GlobalUnlock();
00922
00923 gROOT->SetBatch(kTRUE);
00924 }
00925
00926
00927 void TGWin32::Lock()
00928 {
00929
00930
00931 if (gMainThread && gMainThread->fCritSec) ::EnterCriticalSection(gMainThread->fCritSec);
00932 }
00933
00934
00935 void TGWin32::Unlock()
00936 {
00937
00938
00939 if (gMainThread && gMainThread->fCritSec) ::LeaveCriticalSection(gMainThread->fCritSec);
00940 }
00941
00942
00943 Bool_t TGWin32::Init(void *display)
00944 {
00945
00946
00947 if (!gdk_initialized) {
00948 if (!gdk_init_check(NULL, NULL)) return kFALSE;
00949 gdk_initialized = true;
00950 }
00951
00952 if (!gClipboardAtom) {
00953 gClipboardAtom = gdk_atom_intern("CLIPBOARD", kFALSE);
00954 }
00955
00956 return kTRUE;
00957 }
00958
00959
00960 Int_t TGWin32::OpenDisplay(const char *dpyName)
00961 {
00962
00963
00964 GdkPixmap *pixmp1, *pixmp2;
00965 GdkColor fore, back;
00966 GdkColor color;
00967 GdkGCValues gcvals;
00968 int i;
00969
00970 if (!Init((void*)dpyName)) {
00971 return -1;
00972 }
00973
00974 if (gDebug <= 4) {
00975 gdk_debug_level = gDebug;
00976 } else {
00977 gdk_debug_level = 0;
00978 }
00979
00980 fore.red = fore.green = fore.blue = 0;
00981 back.red = back.green = back.blue = 0;
00982 color.red = color.green = color.blue = 0;
00983
00984 fScreenNumber = 0;
00985 fVisual = gdk_visual_get_best();
00986 fColormap = gdk_colormap_get_system();
00987 fDepth = gdk_visual_get_best_depth();
00988
00989 GetColor(1).fDefined = kTRUE;
00990 gdk_color_black((GdkColormap *)fColormap, &GetColor(1).color);
00991
00992 GetColor(0).fDefined = kTRUE;
00993 gdk_color_white((GdkColormap *)fColormap, &GetColor(0).color);
00994
00995
00996 for (i = 0; i < kMAXGC; i++) {
00997 gGClist[i] = gdk_gc_new(GDK_ROOT_PARENT());
00998 gdk_gc_set_foreground(gGClist[i], &GetColor(1).color);
00999 gdk_gc_set_background(gGClist[i], &GetColor(0).color);
01000 }
01001
01002 gGCline = gGClist[0];
01003 gGCmark = gGClist[1];
01004 gGCfill = gGClist[2];
01005 gGCtext = gGClist[3];
01006 gGCinvt = gGClist[4];
01007 gGCdash = gGClist[5];
01008 gGCpxmp = gGClist[6];
01009
01010 gdk_gc_get_values(gGCtext, &gcvals);
01011 gdk_gc_set_foreground(gGCinvt, &gcvals.background);
01012 gdk_gc_set_background(gGCinvt, &gcvals.foreground);
01013
01014
01015 GdkGCValues echov;
01016 gdk_color_black(fColormap, &echov.foreground);
01017 gdk_color_white(fColormap, &echov.background);
01018 echov.function = GDK_INVERT;
01019 echov.subwindow_mode = GDK_CLIP_BY_CHILDREN;
01020 gGCecho =
01021 gdk_gc_new_with_values((GdkWindow *) GDK_ROOT_PARENT(), &echov,
01022 (GdkGCValuesMask) (GDK_GC_FOREGROUND |
01023 GDK_GC_BACKGROUND |
01024 GDK_GC_FUNCTION |
01025 GDK_GC_SUBWINDOW));
01026
01027 pixmp1 = gdk_bitmap_create_from_data(GDK_ROOT_PARENT(),
01028 (const char *)null_cursor_bits, 16,16);
01029
01030 pixmp2 = gdk_bitmap_create_from_data(GDK_ROOT_PARENT(),
01031 (const char *)null_cursor_bits, 16, 16);
01032
01033 gNullCursor = gdk_cursor_new_from_pixmap((GdkDrawable *)pixmp1, (GdkDrawable *)pixmp2,
01034 &fore, &back, 0, 0);
01035
01036 if (gEnv->GetValue("Win32.UseSysPointers", 0)) {
01037 fUseSysPointers = kTRUE;
01038 fCursors[kBottomLeft] = gdk_syscursor_new((ULong_t)IDC_SIZENESW);
01039 fCursors[kBottomRight] = gdk_syscursor_new((ULong_t)IDC_SIZENWSE);
01040 fCursors[kTopLeft] = gdk_syscursor_new((ULong_t)IDC_SIZENWSE);
01041 fCursors[kTopRight] = gdk_syscursor_new((ULong_t)IDC_SIZENESW);
01042 fCursors[kBottomSide] = gdk_syscursor_new((ULong_t)IDC_SIZENS);
01043 fCursors[kLeftSide] = gdk_syscursor_new((ULong_t)IDC_SIZEWE);
01044 fCursors[kTopSide] = gdk_syscursor_new((ULong_t)IDC_SIZENS);
01045 fCursors[kRightSide] = gdk_syscursor_new((ULong_t)IDC_SIZEWE);
01046 fCursors[kMove] = gdk_syscursor_new((ULong_t)IDC_SIZEALL);
01047 fCursors[kCross] =gdk_syscursor_new((ULong_t)IDC_CROSS);
01048 fCursors[kArrowHor] = gdk_syscursor_new((ULong_t)IDC_SIZEWE);
01049 fCursors[kArrowVer] = gdk_syscursor_new((ULong_t)IDC_SIZENS);
01050 fCursors[kHand] = gdk_syscursor_new((ULong_t)IDC_HAND);
01051 fCursors[kPointer] = gdk_syscursor_new((ULong_t)IDC_ARROW);
01052 fCursors[kCaret] = gdk_syscursor_new((ULong_t)IDC_IBEAM);
01053 fCursors[kWatch] = gdk_syscursor_new((ULong_t)IDC_WAIT);
01054 fCursors[kNoDrop] = gdk_syscursor_new((ULong_t)IDC_NO);
01055 }
01056 else {
01057 fUseSysPointers = kFALSE;
01058 fCursors[kBottomLeft] = gdk_cursor_new(GDK_BOTTOM_LEFT_CORNER);
01059 fCursors[kBottomRight] = gdk_cursor_new(GDK_BOTTOM_RIGHT_CORNER);
01060 fCursors[kTopLeft] = gdk_cursor_new(GDK_TOP_LEFT_CORNER);
01061 fCursors[kTopRight] = gdk_cursor_new(GDK_TOP_RIGHT_CORNER);
01062 fCursors[kBottomSide] = gdk_cursor_new(GDK_BOTTOM_SIDE);
01063 fCursors[kLeftSide] = gdk_cursor_new(GDK_LEFT_SIDE);
01064 fCursors[kTopSide] = gdk_cursor_new(GDK_TOP_SIDE);
01065 fCursors[kRightSide] = gdk_cursor_new(GDK_RIGHT_SIDE);
01066 fCursors[kMove] = gdk_cursor_new(GDK_FLEUR);
01067 fCursors[kCross] =gdk_cursor_new(GDK_CROSSHAIR);
01068 fCursors[kArrowHor] = gdk_cursor_new(GDK_SB_H_DOUBLE_ARROW);
01069 fCursors[kArrowVer] = gdk_cursor_new(GDK_SB_V_DOUBLE_ARROW);
01070 fCursors[kHand] = gdk_cursor_new(GDK_HAND2);
01071 fCursors[kPointer] = gdk_cursor_new(GDK_LEFT_PTR);
01072 fCursors[kCaret] = gdk_cursor_new(GDK_XTERM);
01073
01074 fCursors[kWatch] = gdk_cursor_new(GDK_BUSY);
01075 fCursors[kNoDrop] = gdk_cursor_new(GDK_PIRATE);
01076 }
01077 fCursors[kRotate] = gdk_cursor_new(GDK_EXCHANGE);
01078 fCursors[kArrowRight] = gdk_cursor_new(GDK_ARROW);
01079
01080
01081 fRedDiv = fGreenDiv = fBlueDiv = fRedShift = fGreenShift = fBlueShift = -1;
01082
01083 if ( gdk_visual_get_best_type() == GDK_VISUAL_TRUE_COLOR) {
01084 int i;
01085 for (i = 0; i < int(sizeof(fVisual->blue_mask)*kBitsPerByte); i++) {
01086 if (fBlueShift == -1 && ((fVisual->blue_mask >> i) & 1)) {
01087 fBlueShift = i;
01088 }
01089 if ((fVisual->blue_mask >> i) == 1) {
01090 fBlueDiv = sizeof(UShort_t)*kBitsPerByte - i - 1 + fBlueShift;
01091 break;
01092 }
01093 }
01094 for (i = 0; i < int(sizeof(fVisual->green_mask)*kBitsPerByte); i++) {
01095 if (fGreenShift == -1 && ((fVisual->green_mask >> i) & 1)) {
01096 fGreenShift = i;
01097 }
01098 if ((fVisual->green_mask >> i) == 1) {
01099 fGreenDiv = sizeof(UShort_t)*kBitsPerByte - i - 1 + fGreenShift;
01100 break;
01101 }
01102 }
01103 for (i = 0; i < int(sizeof(fVisual->red_mask)*kBitsPerByte); i++) {
01104 if (fRedShift == -1 && ((fVisual->red_mask >> i) & 1)) {
01105 fRedShift = i;
01106 }
01107 if ((fVisual->red_mask >> i) == 1) {
01108 fRedDiv = sizeof(UShort_t)*kBitsPerByte - i - 1 + fRedShift;
01109 break;
01110 }
01111 }
01112 }
01113
01114 SetName("Win32TTF");
01115 SetTitle("ROOT interface to Win32 with TrueType fonts");
01116
01117 if (!TTF::IsInitialized()) TTF::Init();
01118
01119 if (fDepth > 8) {
01120 TTF::SetSmoothing(kTRUE);
01121 } else {
01122 TTF::SetSmoothing(kFALSE);
01123 }
01124
01125 TGWin32VirtualXProxy::fMaxResponseTime = 1000;
01126 fHasTTFonts = kTRUE;
01127 return 0;
01128 }
01129
01130
01131 Bool_t TGWin32::AllocColor(GdkColormap *cmap, GdkColor *color)
01132 {
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148 if (fRedDiv == -1) {
01149 if ( gdk_color_alloc((GdkColormap *)cmap, (GdkColor *)color) ) return kTRUE;
01150 } else {
01151 color->pixel = (color->red >> fRedDiv) << fRedShift |
01152 (color->green >> fGreenDiv) << fGreenShift |
01153 (color->blue >> fBlueDiv) << fBlueShift;
01154 return kTRUE;
01155 }
01156
01157 return kFALSE;
01158 }
01159
01160
01161 void TGWin32::QueryColors(GdkColormap *cmap, GdkColor *color, Int_t ncolors)
01162 {
01163
01164
01165 ULong_t r, g, b;
01166
01167 if (fRedDiv == -1) {
01168 GdkColorContext *cc = gdk_color_context_new(gdk_visual_get_system(), cmap);
01169 gdk_color_context_query_colors(cc, color, ncolors);
01170 gdk_color_context_free(cc);
01171 } else {
01172 for (Int_t i = 0; i < ncolors; i++) {
01173 r = (color[i].pixel & fVisual->red_mask) >> fRedShift;
01174 color[i].red = UShort_t(r*kBIGGEST_RGB_VALUE/(fVisual->red_mask >> fRedShift));
01175
01176 g = (color[i].pixel & fVisual->green_mask) >> fGreenShift;
01177 color[i].green = UShort_t(g*kBIGGEST_RGB_VALUE/(fVisual->green_mask >> fGreenShift));
01178
01179 b = (color[i].pixel & fVisual->blue_mask) >> fBlueShift;
01180 color[i].blue = UShort_t(b*kBIGGEST_RGB_VALUE/(fVisual->blue_mask >> fBlueShift));
01181 }
01182 }
01183 }
01184
01185
01186 void TGWin32::Align(void)
01187 {
01188
01189
01190
01191
01192 EAlign align = (EAlign) fTextAlign;
01193
01194
01195 if (align == kTLeft || align == kTCenter || align == kTRight) {
01196 fAlign.y = TTF::GetAscent();
01197 } else if (align == kMLeft || align == kMCenter || align == kMRight) {
01198 fAlign.y = TTF::GetAscent()/2;
01199 } else {
01200 fAlign.y = 0;
01201 }
01202
01203 if (align == kTRight || align == kMRight || align == kBRight) {
01204 fAlign.x = TTF::GetWidth();
01205 } else if (align == kTCenter || align == kMCenter || align == kBCenter) {
01206 fAlign.x = TTF::GetWidth()/2;
01207 } else {
01208 fAlign.x = 0;
01209 }
01210
01211 FT_Vector_Transform(&fAlign, TTF::GetRotMatrix());
01212 fAlign.x = fAlign.x >> 6;
01213 fAlign.y = fAlign.y >> 6;
01214 }
01215
01216
01217 void TGWin32::DrawImage(FT_Bitmap *source, ULong_t fore, ULong_t back,
01218 GdkImage *xim, Int_t bx, Int_t by)
01219 {
01220
01221
01222
01223 UChar_t d = 0, *s = source->buffer;
01224
01225 if (TTF::GetSmoothing()) {
01226
01227 static GdkColor col[5];
01228 GdkColor *bcol = 0, *bc;
01229 Int_t x, y;
01230
01231
01232
01233 if (back == (ULong_t) -1 && (UInt_t)source->width) {
01234 ULong_t r, g, b;
01235 Int_t dots, dotcnt;
01236 const Int_t maxdots = 50000;
01237
01238 dots = Int_t(source->width * source->rows);
01239 dots = dots > maxdots ? maxdots : dots;
01240 bcol = new GdkColor[dots];
01241 if (!bcol) return;
01242
01243 bc = bcol;
01244 dotcnt = 0;
01245 for (y = 0; y < (int) source->rows; y++) {
01246 for (x = 0; x < (int) source->width; x++, bc++) {
01247 bc->pixel = GetPixelImage((Drawable_t)xim, bx + x, by + y);
01248 if (++dotcnt >= maxdots) break;
01249 }
01250 }
01251 QueryColors(fColormap, bcol, dots);
01252 r = g = b = 0;
01253 bc = bcol;
01254 dotcnt = 0;
01255 for (y = 0; y < (int) source->rows; y++) {
01256 for (x = 0; x < (int) source->width; x++, bc++) {
01257 r += bc->red;
01258 g += bc->green;
01259 b += bc->blue;
01260 if (++dotcnt >= maxdots) break;
01261 }
01262 }
01263 if (dots != 0) {
01264 r /= dots;
01265 g /= dots;
01266 b /= dots;
01267 }
01268 bc = &col[0];
01269 if (bc->red == r && bc->green == g && bc->blue == b) {
01270 bc->pixel = back;
01271 } else {
01272 bc->pixel = ~back;
01273 bc->red = (UShort_t) r;
01274 bc->green = (UShort_t) g;
01275 bc->blue = (UShort_t) b;
01276 }
01277 }
01278 delete [] bcol;
01279
01280
01281
01282
01283 if (fore != col[4].pixel || back != col[0].pixel) {
01284 col[4].pixel = fore;
01285 if (back != (ULong_t) -1) {
01286 col[3].pixel = back;
01287 QueryColors(fColormap, &col[3], 2);
01288 col[0] = col[3];
01289 } else {
01290 QueryColors(fColormap, &col[4], 1);
01291 }
01292
01293
01294 for (x = 3; x > 0; x--) {
01295 col[x].red = (col[4].red *x + col[0].red *(4-x)) /4;
01296 col[x].green = (col[4].green*x + col[0].green*(4-x)) /4;
01297 col[x].blue = (col[4].blue *x + col[0].blue *(4-x)) /4;
01298 if (!AllocColor(fColormap, &col[x])) {
01299 Warning("DrawImage", "cannot allocate smoothing color");
01300 col[x].pixel = col[x+1].pixel;
01301 }
01302 }
01303 }
01304
01305
01306
01307 for (y = 0; y < (int) source->rows; y++) {
01308 for (x = 0; x < (int) source->width; x++) {
01309 d = *s++ & 0xff;
01310 d = ((d + 10) * 5) / 256;
01311 if (d > 4) d = 4;
01312 if (d && x < (int) source->width) {
01313 ULong_t p = col[d].pixel;
01314 PutPixel((Drawable_t)xim, bx + x, by + y, p);
01315 }
01316 }
01317 }
01318 } else {
01319
01320 UChar_t* row=s;
01321 for (int y = 0; y < (int) source->rows; y++) {
01322 int n = 0;
01323 s = row;
01324 for (int x = 0; x < (int) source->width; x++) {
01325 if (n == 0) d = *s++;
01326 if (TESTBIT(d,7-n)) {
01327 PutPixel((Drawable_t)xim, bx + x, by + y, fore);
01328 }
01329 if (++n == (int) kBitsPerByte) n = 0;
01330 }
01331 row += source->pitch;
01332 }
01333 }
01334 }
01335
01336
01337 void TGWin32::DrawText(Int_t x, Int_t y, Float_t angle, Float_t mgn,
01338 const char *text, ETextMode mode)
01339 {
01340
01341
01342
01343 if (!TTF::IsInitialized()) TTF::Init();
01344 TTF::SetRotationMatrix(angle);
01345 TTF::PrepareString(text);
01346 TTF::LayoutGlyphs();
01347 Align();
01348 RenderString(x, y, mode);
01349 }
01350
01351
01352 GdkImage *TGWin32::GetBackground(Int_t x, Int_t y, UInt_t w, UInt_t h)
01353 {
01354
01355
01356 Window_t cws = GetCurrentWindow();
01357 UInt_t width;
01358 UInt_t height;
01359 Int_t xy;
01360 gVirtualX->GetWindowSize(cws, xy, xy, width, height);
01361
01362 if (x < 0) {
01363 w += x;
01364 x = 0;
01365 }
01366 if (y < 0) {
01367 h += y;
01368 y = 0;
01369 }
01370
01371 if (x+w > width) w = width - x;
01372 if (y+h > height) h = height - y;
01373
01374 return gdk_image_get((GdkDrawable*)cws, x, y, w, h);
01375 }
01376
01377
01378 Bool_t TGWin32::IsVisible(Int_t x, Int_t y, UInt_t w, UInt_t h)
01379 {
01380
01381
01382 Window_t cws = GetCurrentWindow();
01383 UInt_t width;
01384 UInt_t height;
01385 Int_t xy;
01386 gVirtualX->GetWindowSize(cws, xy, xy, width, height);
01387
01388
01389 if ((int)w == 0 || (int)h == 0) return kFALSE;
01390
01391
01392 if (x + (int)w <= 0 || x >= (int)width) return kFALSE;
01393 if (y + (int)h <= 0 || y >= (int)height) return kFALSE;
01394
01395 return kTRUE;
01396 }
01397
01398
01399 void TGWin32::RenderString(Int_t x, Int_t y, ETextMode mode)
01400 {
01401
01402
01403
01404 TTGlyph* glyph = TTF::GetGlyphs();
01405 GdkGCValues gcvals;
01406
01407
01408 Int_t Xoff = 0; if (TTF::GetBox().xMin < 0) Xoff = -TTF::GetBox().xMin;
01409 Int_t Yoff = 0; if (TTF::GetBox().yMin < 0) Yoff = -TTF::GetBox().yMin;
01410 Int_t w = TTF::GetBox().xMax + Xoff;
01411 Int_t h = TTF::GetBox().yMax + Yoff;
01412 Int_t x1 = x-Xoff-fAlign.x;
01413 Int_t y1 = y+Yoff+fAlign.y-h;
01414
01415 if (!IsVisible(x1, y1, w, h)) {
01416 return;
01417 }
01418
01419
01420 UInt_t depth = fDepth;
01421 GdkImage *xim = gdk_image_new(GDK_IMAGE_SHARED, gdk_visual_get_best(), w, h);
01422
01423
01424
01425
01426
01427 ULong_t pixel;
01428 ULong_t bg;
01429
01430 gdk_gc_get_values((GdkGC*)GetGC(3), &gcvals);
01431
01432
01433 if (mode == kClear) {
01434
01435 GdkImage *bim = GetBackground(x1, y1, w, h);
01436 if (!bim) {
01437 Error("DrawText", "error getting background image");
01438 return;
01439 }
01440
01441
01442 Int_t xo = 0, yo = 0;
01443 if (x1 < 0) xo = -x1;
01444 if (y1 < 0) yo = -y1;
01445
01446 for (int yp = 0; yp < (int) bim->height; yp++) {
01447 for (int xp = 0; xp < (int) bim->width; xp++) {
01448 pixel = GetPixelImage((Drawable_t)bim, xp, yp);
01449 PutPixel((Drawable_t)xim, xo+xp, yo+yp, pixel);
01450 }
01451 }
01452
01453 gdk_image_unref((GdkImage *)bim);
01454
01455 bg = (ULong_t) -1;
01456 } else {
01457
01458
01459 GdkImage *bim = GetBackground(x1, y1, w, h);
01460 if (!bim) {
01461 pixel = gcvals.background.pixel;
01462 } else {
01463 pixel = GetPixelImage((Drawable_t)bim, 0, 0);
01464 }
01465 Int_t xo = 0, yo = 0;
01466 if (x1 < 0) xo = -x1;
01467 if (y1 < 0) yo = -y1;
01468
01469 for (int yp = 0; yp < h; yp++) {
01470 for (int xp = 0; xp < (int) w; xp++) {
01471 PutPixel((Drawable_t)xim, xo+xp, yo+yp, pixel);
01472 }
01473 }
01474 if (bim) {
01475 gdk_image_unref((GdkImage *)bim);
01476 bg = (ULong_t) -1;
01477 } else {
01478 bg = pixel;
01479 }
01480 }
01481
01482
01483 glyph = TTF::GetGlyphs();
01484 for (int n = 0; n < TTF::GetNumGlyphs(); n++, glyph++) {
01485 if (FT_Glyph_To_Bitmap(&glyph->fImage,
01486 TTF::GetSmoothing() ? ft_render_mode_normal
01487 : ft_render_mode_mono,
01488 0, 1 )) continue;
01489 FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph->fImage;
01490 FT_Bitmap* source = &bitmap->bitmap;
01491 Int_t bx, by;
01492
01493 bx = bitmap->left+Xoff;
01494 by = h - bitmap->top-Yoff;
01495 DrawImage(source, gcvals.foreground.pixel, bg, xim, bx, by);
01496 }
01497
01498
01499 Window_t cws = GetCurrentWindow();
01500 gdk_draw_image((GdkDrawable *)cws, GetGC(6), xim, 0, 0, x1, y1, w, h);
01501
01502 gdk_image_unref(xim);
01503 }
01504
01505
01506 void TGWin32::SetTextFont(Font_t fontnumber)
01507 {
01508
01509
01510 fTextFont = fontnumber;
01511 TTF::SetTextFont(fontnumber);
01512 }
01513
01514
01515 Int_t TGWin32::SetTextFont(char *fontname, ETextSetMode mode)
01516 {
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526 return TTF::SetTextFont(fontname);
01527 }
01528
01529
01530 void TGWin32::SetTextSize(Float_t textsize)
01531 {
01532
01533
01534 fTextSize = textsize;
01535 TTF::SetTextSize(textsize);
01536 }
01537
01538
01539 void TGWin32::ClearWindow()
01540 {
01541
01542
01543 if (!fWindows) return;
01544
01545 if (!gCws->ispixmap && !gCws->double_buffer) {
01546 gdk_window_set_background(gCws->drawing, (GdkColor *) & GetColor(0).color);
01547 gdk_window_clear(gCws->drawing);
01548 GdiFlush();
01549 } else {
01550 SetColor(gGCpxmp, 0);
01551 gdk_win32_draw_rectangle(gCws->drawing, gGCpxmp, 1,
01552 0, 0, gCws->width, gCws->height);
01553 SetColor(gGCpxmp, 1);
01554 }
01555 }
01556
01557
01558 void TGWin32::ClosePixmap()
01559 {
01560
01561
01562 CloseWindow1();
01563 }
01564
01565
01566 void TGWin32::CloseWindow()
01567 {
01568
01569
01570 CloseWindow1();
01571 }
01572
01573
01574 void TGWin32::CloseWindow1()
01575 {
01576
01577
01578 int wid;
01579
01580 if (gCws->ispixmap) {
01581 gdk_pixmap_unref(gCws->window);
01582 } else {
01583 gdk_window_destroy(gCws->window, kTRUE);
01584 }
01585
01586 if (gCws->buffer) {
01587 gdk_pixmap_unref(gCws->buffer);
01588 }
01589 if (gCws->new_colors) {
01590 gdk_colormap_free_colors((GdkColormap *) fColormap,
01591 (GdkColor *)gCws->new_colors, gCws->ncolors);
01592
01593 delete [] gCws->new_colors;
01594 gCws->new_colors = 0;
01595 }
01596
01597 GdiFlush();
01598 gCws->open = 0;
01599
01600 if (!fWindows) return;
01601
01602
01603 for (wid = 0; wid < fMaxNumberOfWindows; wid++) {
01604 if (fWindows[wid].open) {
01605 gCws = &fWindows[wid];
01606 return;
01607 }
01608 }
01609 gCws = 0;
01610 }
01611
01612
01613 void TGWin32::CopyPixmap(int wid, int xpos, int ypos)
01614 {
01615
01616
01617 if (!fWindows) return;
01618
01619 gTws = &fWindows[wid];
01620 gdk_window_copy_area(gCws->drawing, gGCpxmp, xpos, ypos, gTws->drawing,
01621 0, 0, gTws->width, gTws->height);
01622 GdiFlush();
01623 }
01624
01625
01626 void TGWin32::DrawBox(int x1, int y1, int x2, int y2, EBoxMode mode)
01627 {
01628
01629
01630
01631
01632 if (!fWindows) return;
01633
01634 Int_t x = TMath::Min(x1, x2);
01635 Int_t y = TMath::Min(y1, y2);
01636 Int_t w = TMath::Abs(x2 - x1);
01637 Int_t h = TMath::Abs(y2 - y1);
01638
01639 switch (mode) {
01640
01641 case kHollow:
01642 if (fLineColorModified) UpdateLineColor();
01643 if (fPenModified) UpdateLineStyle();
01644 gdk_win32_draw_rectangle(gCws->drawing, gGCline, 0, x, y, w, h);
01645 break;
01646
01647 case kFilled:
01648 if (fFillStyleModified) UpdateFillStyle();
01649 if (fFillColorModified) UpdateFillColor();
01650 gdk_win32_draw_rectangle(gCws->drawing, gGCfill, 1, x, y, w, h);
01651 break;
01652
01653 default:
01654 break;
01655 }
01656 }
01657
01658
01659 void TGWin32::DrawCellArray(Int_t x1, Int_t y1, Int_t x2, Int_t y2,
01660 Int_t nx, Int_t ny, Int_t *ic)
01661 {
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672 int i, j, icol, ix, iy, w, h, current_icol;
01673
01674 if (!fWindows) return;
01675
01676 current_icol = -1;
01677 w = TMath::Max((x2 - x1) / (nx), 1);
01678 h = TMath::Max((y1 - y2) / (ny), 1);
01679 ix = x1;
01680
01681 if (fFillStyleModified) UpdateFillStyle();
01682 if (fFillColorModified) UpdateFillColor();
01683
01684 for (i = 0; i < nx; i++) {
01685 iy = y1 - h;
01686 for (j = 0; j < ny; j++) {
01687 icol = ic[i + (nx * j)];
01688 if (icol != current_icol) {
01689 gdk_gc_set_foreground(gGCfill, (GdkColor *) & GetColor(icol).color);
01690 current_icol = icol;
01691 }
01692
01693 gdk_win32_draw_rectangle(gCws->drawing, gGCfill, kTRUE, ix, iy, w, h);
01694 iy = iy - h;
01695 }
01696 ix = ix + w;
01697 }
01698 }
01699
01700
01701 void TGWin32::DrawFillArea(int n, TPoint *xyt)
01702 {
01703
01704
01705
01706
01707 int i;
01708 static int lastn = 0;
01709 static GdkPoint *xy = 0;
01710
01711 if (!fWindows) return;
01712
01713 if (fFillStyleModified) UpdateFillStyle();
01714 if (fFillColorModified) UpdateFillColor();
01715
01716 if (lastn!=n) {
01717 delete [] (GdkPoint *)xy;
01718 xy = new GdkPoint[n];
01719 lastn = n;
01720 }
01721 for (i = 0; i < n; i++) {
01722 xy[i].x = xyt[i].fX;
01723 xy[i].y = xyt[i].fY;
01724 }
01725
01726 if (gFillHollow) {
01727 gdk_win32_draw_lines(gCws->drawing, gGCfill, xy, n);
01728 } else {
01729 gdk_win32_draw_polygon(gCws->drawing, gGCfill, 1, xy, n);
01730 }
01731 }
01732
01733
01734 void TGWin32::DrawLine(int x1, int y1, int x2, int y2)
01735 {
01736
01737
01738
01739
01740 if (!fWindows) return;
01741
01742 if (fLineColorModified) UpdateLineColor();
01743 if (fPenModified) UpdateLineStyle();
01744
01745 if (gLineStyle == GDK_LINE_SOLID) {
01746 gdk_draw_line(gCws->drawing, gGCline, x1, y1, x2, y2);
01747 } else {
01748 int i;
01749 gint8 dashes[32];
01750 for (i = 0; i < gDashSize; i++) {
01751 dashes[i] = (gint8) gDashList[i];
01752 }
01753 for (i = gDashSize; i < 32; i++) {
01754 dashes[i] = (gint8) 0;
01755 }
01756 gdk_gc_set_dashes(gGCdash, gDashOffset, dashes, gDashSize);
01757 gdk_draw_line(gCws->drawing, gGCdash, x1, y1, x2, y2);
01758 }
01759 }
01760
01761
01762 void TGWin32::DrawPolyLine(int n, TPoint * xyt)
01763 {
01764
01765
01766
01767
01768 int i;
01769
01770 if (!fWindows) return;
01771
01772 Point_t *xy = new Point_t[n];
01773
01774 for (i = 0; i < n; i++) {
01775 xy[i].fX = xyt[i].fX;
01776 xy[i].fY = xyt[i].fY;
01777 }
01778
01779 if (fLineColorModified) UpdateLineColor();
01780 if (fPenModified) UpdateLineStyle();
01781
01782 if (n > 1) {
01783 if (gLineStyle == GDK_LINE_SOLID) {
01784 gdk_win32_draw_lines(gCws->drawing, gGCline, (GdkPoint *)xy, n);
01785 } else {
01786 int i;
01787 gint8 dashes[32];
01788
01789 for (i = 0; i < gDashSize; i++) {
01790 dashes[i] = (gint8) gDashList[i];
01791 }
01792 for (i = gDashSize; i < 32; i++) {
01793 dashes[i] = (gint8) 0;
01794 }
01795
01796 gdk_gc_set_dashes(gGCdash, gDashOffset, dashes, gDashSize);
01797 gdk_win32_draw_lines(gCws->drawing, (GdkGC*)gGCdash, (GdkPoint *)xy, n);
01798
01799
01800 for (i = 1; i < n; i++) {
01801 int dx = xy[i].fX - xy[i - 1].fX;
01802 int dy = xy[i].fY - xy[i - 1].fY;
01803
01804 if (dx < 0) dx = -dx;
01805 if (dy < 0) dy = -dy;
01806 gDashOffset += dx > dy ? dx : dy;
01807 }
01808 gDashOffset %= gDashLength;
01809 }
01810 } else {
01811 gdk_win32_draw_points( gCws->drawing, gLineStyle == GDK_LINE_SOLID ?
01812 gGCline : gGCdash, (GdkPoint *)xy,1);
01813 }
01814 delete [] xy;
01815 }
01816
01817
01818 void TGWin32::DrawPolyMarker(int n, TPoint *xyt)
01819 {
01820
01821
01822
01823
01824 int i;
01825 static int lastn = 0;
01826 static GdkPoint *xy = 0;
01827
01828 if (!fWindows) return;
01829
01830 if (fMarkerStyleModified) UpdateMarkerStyle();
01831 if (fMarkerColorModified) UpdateMarkerColor();
01832
01833 if (lastn!=n) {
01834 delete [] (GdkPoint *)xy;
01835 xy = new GdkPoint[n];
01836 lastn = n;
01837 }
01838
01839 for (i = 0; i < n; i++) {
01840 xy[i].x = xyt[i].fX;
01841 xy[i].y = xyt[i].fY;
01842 }
01843
01844 if (gMarker.n <= 0) {
01845 gdk_win32_draw_points(gCws->drawing, gGCmark, xy, n);
01846 } else {
01847 int r = gMarker.n / 2;
01848 int m;
01849
01850 for (m = 0; m < n; m++) {
01851 int hollow = 0;
01852 switch (gMarker.type) {
01853 int i;
01854
01855 case 0:
01856 gdk_win32_draw_arc(gCws->drawing, gGCmark, kFALSE, xy[m].x-r, xy[m].y-r,
01857 gMarker.n, gMarker.n, 0, 23040);
01858 break;
01859
01860 case 1:
01861 gdk_win32_draw_arc(gCws->drawing, gGCmark, kTRUE, xy[m].x-r, xy[m].y-r,
01862 gMarker.n, gMarker.n, 0, 23040);
01863 break;
01864
01865 case 2:
01866 hollow = 1;
01867 case 3:
01868 for (i = 0; i < gMarker.n; i++) {
01869 gMarker.xy[i].x += xy[m].x;
01870 gMarker.xy[i].y += xy[m].y;
01871 }
01872 if (hollow) {
01873 gdk_win32_draw_lines(gCws->drawing, gGCmark, (GdkPoint *)gMarker.xy, gMarker.n);
01874 } else {
01875 gdk_win32_draw_polygon(gCws->drawing, gGCmark, 1, (GdkPoint *)gMarker.xy, gMarker.n);
01876 }
01877 for (i = 0; i < gMarker.n; i++) {
01878 gMarker.xy[i].x -= xy[m].x;
01879 gMarker.xy[i].y -= xy[m].y;
01880 }
01881 break;
01882
01883 case 4:
01884 for (i = 0; i < gMarker.n; i += 2) {
01885 gdk_draw_line(gCws->drawing, gGCmark,
01886 xy[m].x + gMarker.xy[i].x,
01887 xy[m].y + gMarker.xy[i].y,
01888 xy[m].x + gMarker.xy[i + 1].x,
01889 xy[m].y + gMarker.xy[i + 1].y);
01890 }
01891 break;
01892 }
01893 }
01894 }
01895 }
01896
01897
01898 void TGWin32::GetCharacterUp(Float_t & chupx, Float_t & chupy)
01899 {
01900
01901
01902 chupx = fCharacterUpX;
01903 chupy = fCharacterUpY;
01904 }
01905
01906
01907 XColor_t &TGWin32::GetColor(Int_t cid)
01908 {
01909
01910
01911
01912 XColor_t *col = (XColor_t*) fColors->GetValue(cid);
01913 if (!col) {
01914 col = new XColor_t;
01915 fColors->Add(cid, (Long_t) col);
01916 }
01917 return *col;
01918 }
01919
01920
01921 Window_t TGWin32::GetCurrentWindow() const
01922 {
01923
01924
01925 return (Window_t)(gCws ? gCws->drawing : 0);
01926 }
01927
01928
01929 GdkGC *TGWin32::GetGC(Int_t which) const
01930 {
01931
01932
01933
01934 if (which >= kMAXGC || which < 0) {
01935 Error("GetGC", "trying to get illegal GdkGC (which = %d)", which);
01936 return 0;
01937 }
01938
01939 return gGClist[which];
01940 }
01941
01942
01943 Int_t TGWin32::GetDoubleBuffer(int wid)
01944 {
01945
01946
01947 if (!fWindows) return 0;
01948
01949 gTws = &fWindows[wid];
01950
01951 if (!gTws->open) {
01952 return -1;
01953 } else {
01954 return gTws->double_buffer;
01955 }
01956 }
01957
01958
01959 void TGWin32::GetGeometry(int wid, int &x, int &y, unsigned int &w,
01960 unsigned int &h)
01961 {
01962
01963
01964
01965
01966
01967
01968 if (!fWindows) return;
01969
01970 if (wid < 0) {
01971 x = 0;
01972 y = 0;
01973
01974 w = gdk_screen_width();
01975 h = gdk_screen_height();
01976 } else {
01977 int depth;
01978 int width, height;
01979
01980 gTws = &fWindows[wid];
01981 gdk_window_get_geometry((GdkDrawable *) gTws->window, &x, &y,
01982 &width, &height, &depth);
01983
01984 gdk_window_get_deskrelative_origin((GdkDrawable *) gTws->window, &x, &y);
01985
01986 if (width > 0 && height > 0) {
01987 gTws->width = width;
01988 gTws->height = height;
01989 }
01990 w = gTws->width;
01991 h = gTws->height;
01992 }
01993 }
01994
01995
01996 const char *TGWin32::DisplayName(const char *dpyName)
01997 {
01998
01999
02000 return "localhost";
02001 }
02002
02003
02004 void TGWin32::GetPlanes(int &nplanes)
02005 {
02006
02007
02008 nplanes = gdk_visual_get_best_depth();
02009 }
02010
02011
02012 void TGWin32::GetRGB(int index, float &r, float &g, float &b)
02013 {
02014
02015
02016 if (index == 0) {
02017 r = g = b = 1.0;
02018 } else if (index == 1) {
02019 r = g = b = 0.0;
02020 } else {
02021 XColor_t &col = GetColor(index);
02022 r = ((float) col.color.red) / ((float) kBIGGEST_RGB_VALUE);
02023 g = ((float) col.color.green) / ((float) kBIGGEST_RGB_VALUE);
02024 b = ((float) col.color.blue) / ((float) kBIGGEST_RGB_VALUE);
02025 }
02026 }
02027
02028
02029 void TGWin32::GetTextExtent(unsigned int &w, unsigned int &h, char *mess)
02030 {
02031
02032
02033
02034
02035
02036 TTF::SetTextFont(gTextFont);
02037 TTF::SetTextSize(fTextSize);
02038 TTF::GetTextExtent(w, h, mess);
02039 }
02040
02041
02042 Window_t TGWin32::GetWindowID(int wid)
02043 {
02044
02045
02046
02047 if (!fWindows) return 0;
02048 return (Window_t) fWindows[wid].window;
02049 }
02050
02051
02052 void TGWin32::MoveWindow(int wid, int x, int y)
02053 {
02054
02055
02056
02057
02058
02059 if (!fWindows) return;
02060
02061 gTws = &fWindows[wid];
02062 if (!gTws->open) return;
02063
02064 gdk_window_move((GdkDrawable *) gTws->window, x, y);
02065 }
02066
02067
02068 Int_t TGWin32::OpenPixmap(unsigned int w, unsigned int h)
02069 {
02070
02071
02072
02073 GdkWindow root;
02074 int wval, hval;
02075 int xx, yy, i, wid;
02076 int ww, hh, border, depth;
02077 wval = w;
02078 hval = h;
02079
02080
02081 again:
02082 for (wid = 0; wid < fMaxNumberOfWindows; wid++) {
02083 if (!fWindows[wid].open) {
02084 fWindows[wid].open = 1;
02085 gCws = &fWindows[wid];
02086 break;
02087 }
02088 }
02089 if (wid == fMaxNumberOfWindows) {
02090 int newsize = fMaxNumberOfWindows + 10;
02091 fWindows = (XWindow_t *) TStorage::ReAlloc(fWindows,
02092 newsize * sizeof(XWindow_t),
02093 fMaxNumberOfWindows *
02094 sizeof(XWindow_t));
02095
02096 for (i = fMaxNumberOfWindows; i < newsize; i++) fWindows[i].open = 0;
02097 fMaxNumberOfWindows = newsize;
02098 goto again;
02099 }
02100
02101 depth =gdk_visual_get_best_depth();
02102 gCws->window = (GdkPixmap *) gdk_pixmap_new(GDK_ROOT_PARENT(),wval,hval,depth);
02103 gdk_drawable_get_size((GdkDrawable *) gCws->window, &ww, &hh);
02104
02105 for (i = 0; i < kMAXGC; i++) {
02106 gdk_gc_set_clip_mask((GdkGC *) gGClist[i], (GdkDrawable *)None);
02107 }
02108
02109 SetColor(gGCpxmp, 0);
02110 gdk_win32_draw_rectangle(gCws->window,(GdkGC *)gGCpxmp, kTRUE,
02111 0, 0, ww, hh);
02112 SetColor(gGCpxmp, 1);
02113
02114
02115 gCws->drawing = gCws->window;
02116 gCws->buffer = 0;
02117 gCws->double_buffer = 0;
02118 gCws->ispixmap = 1;
02119 gCws->clip = 0;
02120 gCws->width = wval;
02121 gCws->height = hval;
02122 gCws->new_colors = 0;
02123
02124 return wid;
02125 }
02126
02127
02128 Int_t TGWin32::InitWindow(ULong_t win)
02129 {
02130
02131
02132
02133 GdkWindowAttr attributes;
02134 unsigned long attr_mask = 0;
02135 int wid;
02136 int xval, yval;
02137 int wval, hval, border, depth;
02138 GdkWindow root;
02139
02140 GdkWindow *wind = (GdkWindow *) win;
02141
02142 gdk_window_get_geometry(wind, &xval, &yval, &wval, &hval, &depth);
02143
02144
02145
02146 again:
02147 for (wid = 0; wid < fMaxNumberOfWindows; wid++) {
02148 if (!fWindows[wid].open) {
02149 fWindows[wid].open = 1;
02150 fWindows[wid].double_buffer = 0;
02151 gCws = &fWindows[wid];
02152 break;
02153 }
02154 }
02155
02156 if (wid == fMaxNumberOfWindows) {
02157 int newsize = fMaxNumberOfWindows + 10;
02158 fWindows =
02159 (XWindow_t *) TStorage::ReAlloc(fWindows,
02160 newsize * sizeof(XWindow_t),
02161 fMaxNumberOfWindows *
02162 sizeof(XWindow_t));
02163
02164 for (int i = fMaxNumberOfWindows; i < newsize; i++) {
02165 fWindows[i].open = 0;
02166 }
02167
02168 fMaxNumberOfWindows = newsize;
02169 goto again;
02170 }
02171
02172 attributes.wclass = GDK_INPUT_OUTPUT;
02173 attributes.event_mask = 0L;
02174 attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_STRUCTURE_MASK |
02175 GDK_PROPERTY_CHANGE_MASK;
02176
02177 if (xval >= 0) {
02178 attributes.x = xval;
02179 } else {
02180 attributes.x = -1.0 * xval;
02181 }
02182
02183 if (yval >= 0) {
02184 attributes.y = yval;
02185 } else {
02186 attributes.y = -1.0 * yval;
02187 }
02188 attributes.width = wval;
02189 attributes.height = hval;
02190 attributes.colormap = gdk_colormap_get_system();
02191 attributes.visual = gdk_window_get_visual(wind);
02192 attributes.override_redirect = TRUE;
02193
02194 if ((attributes.y > 0) && (attributes.x > 0)) {
02195 attr_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_COLORMAP |
02196 GDK_WA_WMCLASS | GDK_WA_NOREDIR;
02197 } else {
02198 attr_mask = GDK_WA_COLORMAP | GDK_WA_WMCLASS | GDK_WA_NOREDIR;
02199 }
02200
02201 if (attributes.visual != NULL) {
02202 attr_mask |= GDK_WA_VISUAL;
02203 }
02204 attributes.window_type = GDK_WINDOW_CHILD;
02205 gCws->window = gdk_window_new(wind, &attributes, attr_mask);
02206 HWND window = (HWND)GDK_DRAWABLE_XID((GdkWindow *)gCws->window);
02207 ::ShowWindow(window, SW_SHOWNORMAL);
02208 ::ShowWindow(window, SW_RESTORE);
02209 ::BringWindowToTop(window);
02210
02211 if (!fUseSysPointers) {
02212 ::SetClassLong(window, GCL_HCURSOR,
02213 (LONG)GDK_CURSOR_XID(fCursors[kPointer]));
02214 }
02215
02216
02217
02218 gCws->drawing = gCws->window;
02219 gCws->buffer = 0;
02220 gCws->double_buffer = 0;
02221 gCws->ispixmap = 0;
02222 gCws->clip = 0;
02223 gCws->width = wval;
02224 gCws->height = hval;
02225 gCws->new_colors = 0;
02226
02227 return wid;
02228 }
02229
02230
02231 void TGWin32::QueryPointer(int &ix, int &iy)
02232 {
02233
02234
02235
02236
02237
02238 GdkModifierType mask;
02239 GdkWindow *retw = gdk_window_get_pointer((GdkWindow *) gCws->window,
02240 &ix, &iy, &mask);
02241 }
02242
02243
02244 void TGWin32::RemovePixmap(GdkDrawable *pix)
02245 {
02246
02247
02248 gdk_pixmap_unref((GdkPixmap *)pix);
02249 }
02250
02251
02252 Int_t TGWin32::RequestLocator(Int_t mode, Int_t ctyp, Int_t & x, Int_t & y)
02253 {
02254
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279 static int xloc = 0;
02280 static int yloc = 0;
02281 static int xlocp = 0;
02282 static int ylocp = 0;
02283 static GdkCursor *cursor = NULL;
02284 Int_t xtmp, ytmp;
02285
02286 GdkEvent *event;
02287 GdkEvent *next_event;
02288 int button_press;
02289 int radius;
02290
02291
02292 if (cursor == NULL) {
02293 if (ctyp > 1) {
02294 gdk_window_set_cursor((GdkWindow *)gCws->window, (GdkCursor *)gNullCursor);
02295 gdk_gc_set_foreground((GdkGC *) gGCecho, &GetColor(0).color);
02296 } else {
02297 if (fUseSysPointers)
02298 cursor = gdk_syscursor_new((ULong_t)IDC_CROSS);
02299 else
02300 cursor = gdk_cursor_new((GdkCursorType)GDK_CROSSHAIR);
02301 gdk_window_set_cursor((GdkWindow *)gCws->window, (GdkCursor *)cursor);
02302 }
02303 }
02304
02305
02306 button_press = 0;
02307
02308
02309
02310 TGWin32VirtualXProxy::fMaxResponseTime = 120000;
02311 while (button_press == 0) {
02312 event = gdk_event_get();
02313
02314 switch (ctyp) {
02315
02316 case 1:
02317 break;
02318
02319 case 2:
02320 gdk_draw_line(gCws->window, gGCecho, xloc, 0, xloc, gCws->height);
02321 gdk_draw_line(gCws->window, gGCecho, 0, yloc, gCws->width, yloc);
02322 break;
02323
02324 case 3:
02325 radius = (int) TMath::Sqrt((double)((xloc - xlocp) * (xloc - xlocp) +
02326 (yloc - ylocp) * (yloc - ylocp)));
02327
02328 gdk_win32_draw_arc(gCws->window, gGCecho, kFALSE,
02329 xlocp - radius, ylocp - radius,
02330 2 * radius, 2 * radius, 0, 23040);
02331 break;
02332
02333 case 4:
02334 gdk_draw_line(gCws->window, gGCecho, xlocp, ylocp, xloc, yloc);
02335 break;
02336
02337 case 5:
02338 gdk_win32_draw_rectangle( gCws->window, gGCecho, kFALSE,
02339 TMath::Min(xlocp, xloc), TMath::Min(ylocp, yloc),
02340 TMath::Abs(xloc - xlocp), TMath::Abs(yloc - ylocp));
02341 break;
02342
02343 default:
02344 break;
02345 }
02346
02347 xloc = event->button.x;
02348 yloc = event->button.y;
02349
02350 switch (event->type) {
02351
02352 case GDK_LEAVE_NOTIFY:
02353 if (mode == 0) {
02354 while (1) {
02355 event = gdk_event_get();
02356
02357 if (event->type == GDK_ENTER_NOTIFY) {
02358 gdk_event_free(event);
02359 break;
02360 }
02361 gdk_event_free(event);
02362 }
02363 } else {
02364 button_press = -2;
02365 }
02366 break;
02367
02368 case GDK_BUTTON_PRESS:
02369 button_press = event->button.button;
02370 xlocp = event->button.x;
02371 ylocp = event->button.y;
02372 gdk_cursor_unref(cursor);
02373 cursor = 0;
02374 break;
02375
02376 case GDK_BUTTON_RELEASE:
02377 if (mode == 1) {
02378 button_press = 10 + event->button.button;
02379 xlocp = event->button.x;
02380 ylocp = event->button.y;
02381 }
02382 break;
02383
02384 case GDK_KEY_PRESS:
02385 if (mode == 1) {
02386 button_press = event->key.keyval;
02387 xlocp = event->button.x;
02388 ylocp = event->button.y;
02389 }
02390 break;
02391
02392 case GDK_KEY_RELEASE:
02393 if (mode == 1) {
02394 button_press = -1 * (int)(event->key.keyval);
02395 xlocp = event->button.x;
02396 ylocp = event->button.y;
02397 }
02398 break;
02399
02400 default:
02401 break;
02402 }
02403
02404 xtmp = event->button.x;
02405 ytmp = event->button.y;
02406
02407 gdk_event_free(event);
02408
02409 if (mode == 1) {
02410 if (button_press == 0) {
02411 button_press = -1;
02412 }
02413 break;
02414 }
02415 }
02416 TGWin32VirtualXProxy::fMaxResponseTime = 1000;
02417
02418 x = xtmp;
02419 y = ytmp;
02420
02421 return button_press;
02422 }
02423
02424
02425 Int_t TGWin32::RequestString(int x, int y, char *text)
02426 {
02427
02428
02429
02430
02431
02432
02433
02434
02435 static GdkCursor *cursor = NULL;
02436 static int percent = 0;
02437 static GdkWindow *CurWnd;
02438 HWND focuswindow;
02439 int focusrevert;
02440 GdkEvent *event;
02441 KeySym keysym;
02442 int key = -1;
02443 int len_text = strlen(text);
02444 int nt;
02445 int pt;
02446 MSG msg;
02447
02448 CurWnd = (GdkWindow *)gCws->window;
02449
02450 if (cursor == NULL) {
02451 if (fUseSysPointers)
02452 cursor = gdk_syscursor_new((ULong_t)IDC_HELP);
02453 else
02454 cursor = gdk_cursor_new((GdkCursorType)GDK_QUESTION_ARROW);
02455 }
02456 if (cursor != 0) {
02457 gdk_window_set_cursor(CurWnd, cursor);
02458 }
02459 for (nt = len_text; nt > 0 && text[nt - 1] == ' '; nt--);
02460
02461 pt = nt;
02462 focuswindow = ::SetFocus((HWND)GDK_DRAWABLE_XID(CurWnd));
02463
02464
02465
02466 TGWin32VirtualXProxy::fMaxResponseTime = 120000;
02467 TTF::SetTextFont(gTextFont);
02468 TTF::SetTextSize(fTextSize);
02469 do {
02470 char tmp[2];
02471 char keybuf[8];
02472 char nbytes;
02473 UInt_t dx, ddx, h;
02474 int i;
02475
02476 if (EventsPending()) {
02477 event = gdk_event_get();
02478 } else {
02479 gSystem->ProcessEvents();
02480 ::SleepEx(10, kTRUE);
02481 continue;
02482 }
02483
02484 DrawText(x, y, 0.0, 1.0, text, kOpaque);
02485 TTF::GetTextExtent(dx, h, text);
02486 DrawText(x+dx, y, 0.0, 1.0, " ", kOpaque);
02487
02488 if (pt == 0) {
02489 dx = 0;
02490 } else {
02491 char *stmp = new char[pt+1];
02492 strncpy(stmp, text, pt);
02493 stmp[pt] = '\0';
02494 TTF::GetTextExtent(ddx, h, stmp);
02495 dx = ddx;
02496 delete stmp;
02497 }
02498
02499 if (pt < len_text) {
02500 tmp[0] = text[pt];
02501 tmp[1] = '\0';
02502 DrawText(x+dx, y, 0.0, 1.0, tmp, kOpaque);
02503 } else {
02504 DrawText(x+dx, y, 0.0, 1.0, " ", kOpaque);
02505 }
02506
02507 if (event != NULL) {
02508 switch (event->type) {
02509 case GDK_BUTTON_PRESS:
02510 case GDK_ENTER_NOTIFY:
02511 focuswindow = ::SetFocus((HWND)GDK_DRAWABLE_XID(CurWnd));
02512 break;
02513
02514 case GDK_LEAVE_NOTIFY:
02515 ::SetFocus(focuswindow);
02516 break;
02517 case GDK_KEY_PRESS:
02518 nbytes = event->key.length;
02519 for (i = 0; i < nbytes; i++) {
02520 keybuf[i] = event->key.string[i];
02521 }
02522 keysym = event->key.keyval;
02523 switch (keysym) {
02524 case GDK_BackSpace:
02525 keybuf[0] = 0x08;
02526 nbytes = 1;
02527 break;
02528 case GDK_Return:
02529 keybuf[0] = 0x0d;
02530 nbytes = 1;
02531 break;
02532 case GDK_Delete:
02533 keybuf[0] = 0x7f;
02534 nbytes = 1;
02535 break;
02536 case GDK_Escape:
02537 keybuf[0] = 0x1b;
02538 nbytes = 1;
02539 break;
02540 case GDK_Home:
02541 keybuf[0] = 0x01;
02542 nbytes = 1;
02543 break;
02544 case GDK_Left:
02545 keybuf[0] = 0x02;
02546 nbytes = 1;
02547 break;
02548 case GDK_Right:
02549 keybuf[0] = 0x06;
02550 nbytes = 1;
02551 break;
02552 case GDK_End:
02553 keybuf[0] = 0x05;
02554 nbytes = 1;
02555 break;
02556 }
02557 if (nbytes == 1) {
02558 if (isascii(keybuf[0]) && isprint(keybuf[0])) {
02559
02560 if (nt < len_text) {
02561 nt++;
02562 }
02563 for (i = nt - 1; i > pt; i--) {
02564 text[i] = text[i - 1];
02565 }
02566 if (pt < len_text) {
02567 text[pt] = keybuf[0];
02568 pt++;
02569 }
02570 } else {
02571 switch (keybuf[0]) {
02572
02573
02574 case 0x08:
02575 case 0x7f:
02576
02577 if (pt > 0) {
02578 for (i = pt; i < nt; i++) {
02579 text[i - 1] = text[i];
02580 }
02581 text[nt - 1] = ' ';
02582 nt--;
02583 pt--;
02584 }
02585 break;
02586 case 0x01:
02587
02588 pt = 0;
02589 break;
02590 case 0x02:
02591
02592 if (pt > 0) {
02593 pt--;
02594 }
02595 break;
02596 case 0x04:
02597
02598 if (pt > 0) {
02599 for (i = pt; i < nt; i++) {
02600 text[i - 1] = text[i];
02601 }
02602 text[nt - 1] = ' ';
02603 pt--;
02604 }
02605 break;
02606 case 0x05:
02607
02608 pt = nt;
02609 break;
02610
02611 case 0x06:
02612
02613 if (pt < nt) {
02614 pt++;
02615 }
02616 break;
02617 case 0x0b:
02618
02619 for (i = pt; i < nt; i++)
02620 text[i] = ' ';
02621 nt = pt;
02622 break;
02623 case 0x14:
02624
02625 if (pt > 0) {
02626 char c = text[pt];
02627 text[pt] = text[pt - 1];
02628 text[pt - 1] = c;
02629 }
02630 break;
02631 case 0x0A:
02632 case 0x0D:
02633 key = 1;
02634 break;
02635 case 0x1B:
02636 key = 0;
02637 break;
02638
02639 default:
02640 gSystem->Beep();
02641 break;
02642 }
02643 }
02644 }
02645 default:
02646 SetInputFocus((Window_t)gCws->window);
02647 break;
02648 }
02649 gdk_event_free(event);
02650 }
02651 } while (key < 0);
02652 TGWin32VirtualXProxy::fMaxResponseTime = 1000;
02653 ::SetFocus(focuswindow);
02654 SetInputFocus((Window_t)CurWnd);
02655
02656 gdk_window_set_cursor(CurWnd, (GdkCursor *)fCursors[kPointer]);
02657 if (cursor != 0) {
02658 gdk_cursor_unref(cursor);
02659 cursor = 0;
02660 }
02661
02662 return key;
02663 }
02664
02665
02666 void TGWin32::RescaleWindow(int wid, unsigned int w, unsigned int h)
02667 {
02668
02669
02670
02671
02672
02673 int i;
02674
02675 if (!fWindows) return;
02676
02677 gTws = &fWindows[wid];
02678 if (!gTws->open)
02679 return;
02680
02681
02682 if (gTws->width == w && gTws->height == h)
02683 return;
02684
02685 gdk_window_resize((GdkWindow *) gTws->window, w, h);
02686
02687 if (gTws->buffer) {
02688
02689 if (gTws->width < w || gTws->height < h) {
02690 gdk_pixmap_unref(gTws->buffer);
02691 gTws->buffer = gdk_pixmap_new(GDK_ROOT_PARENT(),
02692 w, h, gdk_visual_get_best_depth());
02693 }
02694 for (i = 0; i < kMAXGC; i++) {
02695 gdk_gc_set_clip_mask(gGClist[i], None);
02696 }
02697 SetColor(gGCpxmp, 0);
02698 gdk_win32_draw_rectangle(gTws->buffer, gGCpxmp, 1, 0, 0, w, h);
02699 SetColor(gGCpxmp, 1);
02700
02701 if (gTws->double_buffer) gTws->drawing = gTws->buffer;
02702 }
02703 gTws->width = w;
02704 gTws->height = h;
02705 }
02706
02707
02708 int TGWin32::ResizePixmap(int wid, unsigned int w, unsigned int h)
02709 {
02710
02711
02712
02713
02714 GdkWindow root;
02715 int wval, hval;
02716 int xx, yy, i;
02717 int ww, hh, border, depth;
02718 wval = w;
02719 hval = h;
02720
02721 if (!fWindows) return 0;
02722
02723 gTws = &fWindows[wid];
02724
02725
02726
02727
02728
02729
02730 if (gTws->width >= wval - 1 && gTws->width <= wval + 1 &&
02731 gTws->height >= hval - 1 && gTws->height <= hval + 1)
02732 return 0;
02733
02734
02735 if (gTws->width < wval || gTws->height < hval) {
02736 gdk_pixmap_unref((GdkPixmap *)gTws->window);
02737 depth = gdk_visual_get_best_depth();
02738 gTws->window = gdk_pixmap_new(GDK_ROOT_PARENT(), wval, hval, depth);
02739 }
02740
02741 gdk_drawable_get_size(gTws->window, &ww, &hh);
02742
02743 for (i = 0; i < kMAXGC; i++) {
02744 gdk_gc_set_clip_mask((GdkGC *) gGClist[i], (GdkDrawable *)None);
02745 }
02746
02747 SetColor(gGCpxmp, 0);
02748 gdk_win32_draw_rectangle(gTws->window,(GdkGC *)gGCpxmp, kTRUE, 0, 0, ww, hh);
02749 SetColor(gGCpxmp, 1);
02750
02751
02752 gTws->drawing = gTws->window;
02753 gTws->width = wval;
02754 gTws->height = hval;
02755 return 1;
02756 }
02757
02758
02759 void TGWin32::ResizeWindow(int wid)
02760 {
02761
02762
02763 int i;
02764 int xval = 0, yval = 0;
02765 GdkWindow *win, *root = NULL;
02766 int wval = 0, hval = 0, depth = 0;
02767
02768 if (!fWindows) return;
02769
02770 gTws = &fWindows[wid];
02771
02772 win = (GdkWindow *) gTws->window;
02773 gdk_window_get_geometry(win, &xval, &yval,
02774 &wval, &hval, &depth);
02775
02776
02777 if (gTws->width == wval && gTws->height == hval) {
02778 return;
02779 }
02780
02781 gdk_window_resize((GdkWindow *) gTws->window, wval, hval);
02782
02783 if (gTws->buffer) {
02784 if (gTws->width < wval || gTws->height < hval) {
02785 gdk_pixmap_unref((GdkPixmap *)gTws->buffer);
02786 depth = gdk_visual_get_best_depth();
02787 gTws->buffer = (GdkPixmap *) gdk_pixmap_new(GDK_ROOT_PARENT(),
02788 wval, hval, depth);
02789 }
02790
02791 for (i = 0; i < kMAXGC; i++) {
02792 gdk_gc_set_clip_mask((GdkGC *) gGClist[i], (GdkDrawable *)None);
02793 }
02794
02795 SetColor(gGCpxmp, 0);
02796 gdk_win32_draw_rectangle(gTws->buffer,(GdkGC *)gGCpxmp, kTRUE, 0, 0, wval, hval);
02797
02798 SetColor(gGCpxmp, 1);
02799
02800 if (gTws->double_buffer) gTws->drawing = gTws->buffer;
02801 }
02802
02803 gTws->width = wval;
02804 gTws->height = hval;
02805 }
02806
02807
02808 void TGWin32::SelectWindow(int wid)
02809 {
02810
02811
02812 int i;
02813 GdkRectangle rect;
02814
02815 if (!fWindows || wid < 0 || wid >= fMaxNumberOfWindows || !fWindows[wid].open) {
02816 return;
02817 }
02818
02819 gCws = &fWindows[wid];
02820
02821 if (gCws->clip && !gCws->ispixmap && !gCws->double_buffer) {
02822 rect.x = gCws->xclip;
02823 rect.y = gCws->yclip;
02824 rect.width = gCws->wclip;
02825 rect.height = gCws->hclip;
02826
02827 for (i = 0; i < kMAXGC; i++) {
02828 gdk_gc_set_clip_rectangle((GdkGC *) gGClist[i], &rect);
02829 }
02830 } else {
02831 for (i = 0; i < kMAXGC; i++) {
02832 gdk_gc_set_clip_mask((GdkGC *) gGClist[i], (GdkDrawable *)None);
02833 }
02834 }
02835 }
02836
02837
02838 void TGWin32::SetCharacterUp(Float_t chupx, Float_t chupy)
02839 {
02840
02841
02842 if (chupx == fCharacterUpX && chupy == fCharacterUpY) return;
02843
02844 if (chupx == 0 && chupy == 0) {
02845 fTextAngle = 0;
02846 } else if (chupx == 0 && chupy == 1) {
02847 fTextAngle = 0;
02848 } else if (chupx == -1 && chupy == 0) {
02849 fTextAngle = 90;
02850 } else if (chupx == 0 && chupy == -1) {
02851 fTextAngle = 180;
02852 } else if (chupx == 1 && chupy == 0) {
02853 fTextAngle = 270;
02854 } else {
02855 fTextAngle =
02856 ((TMath::
02857 ACos(chupx / TMath::Sqrt(chupx * chupx + chupy * chupy)) *
02858 180.) / 3.14159) - 90;
02859 if (chupy < 0) fTextAngle = 180 - fTextAngle;
02860 if (TMath::Abs(fTextAngle) <= 0.01) fTextAngle = 0;
02861 }
02862 fCharacterUpX = chupx;
02863 fCharacterUpY = chupy;
02864 }
02865
02866
02867 void TGWin32::SetClipOFF(int wid)
02868 {
02869
02870
02871 if (!fWindows) return;
02872
02873 gTws = &fWindows[wid];
02874 gTws->clip = 0;
02875
02876 for (int i = 0; i < kMAXGC; i++) {
02877 gdk_gc_set_clip_mask((GdkGC *) gGClist[i], (GdkDrawable *)None);
02878 }
02879 }
02880
02881
02882 void TGWin32::SetClipRegion(int wid, int x, int y, unsigned int w,
02883 unsigned int h)
02884 {
02885
02886
02887
02888
02889
02890 if (!fWindows) return;
02891
02892 gTws = &fWindows[wid];
02893 gTws->xclip = x;
02894 gTws->yclip = y;
02895 gTws->wclip = w;
02896 gTws->hclip = h;
02897 gTws->clip = 1;
02898 GdkRectangle rect;
02899
02900 if (gTws->clip && !gTws->ispixmap && !gTws->double_buffer) {
02901 rect.x = gTws->xclip;
02902 rect.y = gTws->yclip;
02903 rect.width = gTws->wclip;
02904 rect.height = gTws->hclip;
02905
02906 for (int i = 0; i < kMAXGC; i++) {
02907 gdk_gc_set_clip_rectangle((GdkGC *)gGClist[i], &rect);
02908 }
02909 }
02910 }
02911
02912
02913 ULong_t TGWin32::GetPixel(Color_t ci)
02914 {
02915
02916
02917 TColor *color = gROOT->GetColor(ci);
02918 if (color)
02919 SetRGB(ci, color->GetRed(), color->GetGreen(), color->GetBlue());
02920 XColor_t &col = GetColor(ci);
02921 return col.color.pixel;
02922 }
02923
02924
02925 void TGWin32::SetColor(GdkGC *gc, int ci)
02926 {
02927
02928
02929 GdkGCValues gcvals;
02930 GdkColor color;
02931
02932 if (ci<=0) ci = 10;
02933
02934 TColor *clr = gROOT->GetColor(ci);
02935 if (clr)
02936 SetRGB(ci, clr->GetRed(), clr->GetGreen(), clr->GetBlue());
02937
02938 XColor_t &col = GetColor(ci);
02939 if (fColormap && !col.fDefined) {
02940 col = GetColor(0);
02941 } else if (!fColormap && (ci < 0 || ci > 1)) {
02942 col = GetColor(0);
02943 }
02944
02945 if (fDrawMode == kXor) {
02946 gdk_gc_get_values(gc, &gcvals);
02947
02948 color.pixel = col.color.pixel ^ gcvals.background.pixel;
02949 color.red = GetRValue(color.pixel);
02950 color.green = GetGValue(color.pixel);
02951 color.blue = GetBValue(color.pixel);
02952 gdk_gc_set_foreground(gc, &color);
02953
02954 } else {
02955 gdk_gc_set_foreground(gc, &col.color);
02956
02957
02958 gdk_gc_get_values(gc, &gcvals);
02959
02960 if (gcvals.foreground.pixel != gcvals.background.pixel) {
02961 gdk_gc_set_background(gc, &GetColor(!ci).color);
02962 }
02963 }
02964 }
02965
02966
02967 void TGWin32::SetCursor(int wid, ECursor cursor)
02968 {
02969
02970
02971 if (!fWindows) return;
02972
02973 gTws = &fWindows[wid];
02974 gdk_window_set_cursor((GdkWindow *)gTws->window, (GdkCursor *)fCursors[cursor]);
02975 }
02976
02977
02978 void TGWin32::SetCursor(Window_t id, Cursor_t curid)
02979 {
02980
02981
02982 if (!id) return;
02983
02984 static GdkWindow *lid = 0;
02985 static GdkCursor *lcur = 0;
02986
02987 if ((lid == (GdkWindow *)id) && (lcur==(GdkCursor *)curid)) return;
02988 lid = (GdkWindow *)id;
02989 lcur = (GdkCursor *)curid;
02990
02991 gdk_window_set_cursor((GdkWindow *) id, (GdkCursor *)curid);
02992 }
02993
02994
02995 void TGWin32::SetDoubleBuffer(int wid, int mode)
02996 {
02997
02998
02999
03000
03001
03002
03003 if (!fWindows) return;
03004
03005 if (wid == 999) {
03006 for (int i = 0; i < fMaxNumberOfWindows; i++) {
03007 gTws = &fWindows[i];
03008 if (gTws->open) {
03009 switch (mode) {
03010 case 1:
03011 SetDoubleBufferON();
03012 break;
03013 default:
03014 SetDoubleBufferOFF();
03015 break;
03016 }
03017 }
03018 }
03019 } else {
03020 gTws = &fWindows[wid];
03021 if (!gTws->open) return;
03022
03023 switch (mode) {
03024 case 1:
03025 SetDoubleBufferON();
03026 return;
03027 default:
03028 SetDoubleBufferOFF();
03029 return;
03030 }
03031 }
03032 }
03033
03034
03035 void TGWin32::SetDoubleBufferOFF()
03036 {
03037
03038
03039 if (!gTws->double_buffer) return;
03040 gTws->double_buffer = 0;
03041 gTws->drawing = gTws->window;
03042 }
03043
03044
03045 void TGWin32::SetDoubleBufferON()
03046 {
03047
03048
03049 Int_t depth;
03050
03051 if (!fWindows || gTws->double_buffer || gTws->ispixmap) return;
03052
03053 if (!gTws->buffer) {
03054 gTws->buffer = gdk_pixmap_new(GDK_ROOT_PARENT(),
03055 gTws->width, gTws->height,
03056 gdk_visual_get_best_depth());
03057 SetColor(gGCpxmp, 0);
03058 gdk_win32_draw_rectangle(gTws->buffer, gGCpxmp, 1, 0, 0, gTws->width,
03059 gTws->height);
03060 SetColor(gGCpxmp, 1);
03061 }
03062 for (int i = 0; i < kMAXGC; i++) {
03063 gdk_gc_set_clip_mask(gGClist[i], None);
03064 }
03065 gTws->double_buffer = 1;
03066 gTws->drawing = gTws->buffer;
03067 }
03068
03069
03070 void TGWin32::SetDrawMode(EDrawMode mode)
03071 {
03072
03073
03074
03075
03076
03077
03078
03079
03080 int i;
03081
03082 switch (mode) {
03083 case kCopy:
03084 for (i = 0; i < kMAXGC; i++) {
03085 gdk_gc_set_function(gGClist[i], GDK_COPY);
03086 }
03087 break;
03088
03089 case kXor:
03090 for (i = 0; i < kMAXGC; i++) {
03091 gdk_gc_set_function(gGClist[i], GDK_XOR);
03092 }
03093 break;
03094
03095 case kInvert:
03096 for (i = 0; i < kMAXGC; i++) {
03097 gdk_gc_set_function(gGClist[i], GDK_INVERT);
03098 }
03099 break;
03100 }
03101 fDrawMode = mode;
03102 }
03103
03104
03105 void TGWin32::SetFillColor(Color_t cindex)
03106 {
03107
03108
03109 Int_t indx = Int_t(cindex);
03110
03111 if (!gStyle->GetFillColor() && cindex > 1) {
03112 indx = 0;
03113 }
03114
03115 fFillColor = indx;
03116 fFillColorModified = kTRUE;
03117 }
03118
03119
03120 void TGWin32::UpdateFillColor()
03121 {
03122
03123
03124 if (fFillColor >= 0) {
03125 SetColor(gGCfill, fFillColor);
03126 }
03127
03128
03129 if (gFillPattern != NULL) {
03130 gdk_pixmap_unref(gFillPattern);
03131 gFillPattern = NULL;
03132 }
03133 fFillColorModified = kFALSE;
03134 }
03135
03136
03137 void TGWin32::SetFillStyle(Style_t fstyle)
03138 {
03139
03140
03141
03142
03143 if (fFillStyle==fstyle) return;
03144
03145 fFillStyle = fstyle;
03146 fFillStyleModified = kTRUE;
03147 }
03148
03149
03150 void TGWin32::UpdateFillStyle()
03151 {
03152
03153
03154 char* pchar;
03155 static int current_fasi = 0;
03156
03157 Int_t style = fFillStyle / 1000;
03158 Int_t fasi = fFillStyle % 1000;
03159
03160 switch (style) {
03161
03162 case 1:
03163 gFillHollow = 0;
03164 gdk_gc_set_fill(gGCfill, GDK_SOLID);
03165 break;
03166
03167 case 2:
03168 gFillHollow = 1;
03169 break;
03170
03171 case 3:
03172 gFillHollow = 0;
03173 gdk_gc_set_fill(gGCfill, GDK_STIPPLED);
03174
03175 if (fasi != current_fasi) {
03176 if (gFillPattern != NULL) {
03177 gdk_pixmap_unref(gFillPattern);
03178 gFillPattern = NULL;
03179 }
03180 int stn = (fasi >= 1 && fasi <=25) ? fasi : 2;
03181 gFillPattern = gdk_bitmap_create_from_data(GDK_ROOT_PARENT(),
03182 (const char *)gStipples[stn], 16, 16);
03183 gdk_gc_set_stipple(gGCfill, gFillPattern);
03184 current_fasi = fasi;
03185 }
03186 break;
03187
03188 default:
03189 gFillHollow = 1;
03190 }
03191
03192 fFillStyleModified = kFALSE;
03193 }
03194
03195
03196 void TGWin32::SetInput(int inp)
03197 {
03198
03199
03200 EnableWindow((HWND) GDK_DRAWABLE_XID(gCws->window), inp);
03201 }
03202
03203
03204 void TGWin32::SetLineColor(Color_t cindex)
03205 {
03206
03207
03208 if ((cindex < 0) || (cindex==fLineColor)) return;
03209
03210 fLineColor = cindex;
03211 fLineColorModified = kTRUE;
03212 }
03213
03214
03215 void TGWin32::UpdateLineColor()
03216 {
03217
03218
03219 SetColor(gGCline, Int_t(fLineColor));
03220 SetColor(gGCdash, Int_t(fLineColor));
03221 fLineColorModified = kFALSE;
03222 }
03223
03224
03225 void TGWin32::SetLineType(int n, int *dash)
03226 {
03227
03228
03229
03230
03231
03232
03233
03234
03235
03236 if (n <= 0) {
03237 gLineStyle = GDK_LINE_SOLID;
03238 gdk_gc_set_line_attributes(gGCline, fLineWidth,
03239 (GdkLineStyle)gLineStyle,
03240 (GdkCapStyle) gCapStyle,
03241 (GdkJoinStyle) gJoinStyle);
03242 } else {
03243 int i, j;
03244 gDashSize = TMath::Min((int)sizeof(gDashList),n);
03245 gDashLength = 0;
03246 for (i = 0; i < gDashSize; i++) {
03247 gDashList[i] = dash[i];
03248 gDashLength += gDashList[i];
03249 }
03250 gDashOffset = 0;
03251 gLineStyle = GDK_LINE_ON_OFF_DASH;
03252 gdk_gc_set_line_attributes(gGCdash, fLineWidth,
03253 (GdkLineStyle) gLineStyle,
03254 (GdkCapStyle) gCapStyle,
03255 (GdkJoinStyle) gJoinStyle);
03256 }
03257 fPenModified = kFALSE;
03258 }
03259
03260
03261 void TGWin32::SetLineStyle(Style_t lstyle)
03262 {
03263
03264
03265 if (fLineStyle == lstyle) return;
03266
03267 fLineStyle = lstyle;
03268 fPenModified = kTRUE;
03269 }
03270
03271
03272 void TGWin32::UpdateLineStyle()
03273 {
03274
03275
03276 static Int_t dashed[2] = { 3, 3 };
03277 static Int_t dotted[2] = { 1, 2 };
03278 static Int_t dasheddotted[4] = { 3, 4, 1, 4 };
03279
03280 if (fLineStyle <= 1) {
03281 SetLineType(0, 0);
03282 } else if (fLineStyle == 2) {
03283 SetLineType(2, dashed);
03284 } else if (fLineStyle == 3) {
03285 SetLineType(2, dotted);
03286 } else if (fLineStyle == 4) {
03287 SetLineType(4, dasheddotted);
03288 } else {
03289 TString st = (TString)gStyle->GetLineStyleString(fLineStyle);
03290 TObjArray *tokens = st.Tokenize(" ");
03291 Int_t nt;
03292 nt = tokens->GetEntries();
03293 Int_t *linestyle = new Int_t[nt];
03294 for (Int_t j = 0; j<nt; j++) {
03295 Int_t it;
03296 sscanf(((TObjString*)tokens->At(j))->GetName(), "%d", &it);
03297 linestyle[j] = (Int_t)(it/4);
03298 }
03299 SetLineType(nt,linestyle);
03300 delete [] linestyle;
03301 delete tokens;
03302 }
03303 fPenModified = kFALSE;
03304 }
03305
03306
03307 void TGWin32::SetLineWidth(Width_t width)
03308 {
03309
03310
03311
03312 if ((fLineWidth==width) || (width<0)) return;
03313
03314 if (width == 1) {
03315 fLineWidth = 0;
03316 } else {
03317 fLineWidth = width;
03318 }
03319
03320 fPenModified = kTRUE;
03321 }
03322
03323
03324 void TGWin32::SetMarkerColor(Color_t cindex)
03325 {
03326
03327
03328 if ((cindex<0) || (cindex==fMarkerColor)) return;
03329 fMarkerColor = cindex;
03330 fMarkerColorModified = kTRUE;
03331 }
03332
03333
03334 void TGWin32::UpdateMarkerColor()
03335 {
03336
03337
03338 SetColor(gGCmark, Int_t(fMarkerColor));
03339 fMarkerColorModified = kFALSE;
03340 }
03341
03342
03343 void TGWin32::SetMarkerSize(Float_t msize)
03344 {
03345
03346
03347
03348 if ((msize==fMarkerSize) || (msize<0)) return;
03349
03350 fMarkerSize = msize;
03351 SetMarkerStyle(-fMarkerStyle);
03352 }
03353
03354
03355 void TGWin32::SetMarkerType(int type, int n, GdkPoint * xy)
03356 {
03357
03358
03359
03360
03361
03362
03363
03364
03365
03366
03367
03368
03369
03370 gMarker.type = type;
03371 gMarker.n = n < kMAXMK ? n : kMAXMK;
03372 if (gMarker.type >= 2) {
03373 for (int i = 0; i < gMarker.n; i++) {
03374 gMarker.xy[i] = xy[i];
03375 }
03376 }
03377 }
03378
03379
03380 void TGWin32::SetMarkerStyle(Style_t markerstyle)
03381 {
03382
03383
03384 if ((fMarkerStyle==markerstyle) || (markerstyle >= 35)) return;
03385 fMarkerStyle = TMath::Abs(markerstyle);
03386 fMarkerStyleModified = kTRUE;
03387 }
03388
03389
03390 void TGWin32::UpdateMarkerStyle()
03391 {
03392
03393
03394 static GdkPoint shape[15];
03395
03396 Int_t im = Int_t(4 * fMarkerSize + 0.5);
03397
03398 if (fMarkerStyle == 2) {
03399
03400 shape[0].x = -im;
03401 shape[0].y = 0;
03402 shape[1].x = im;
03403 shape[1].y = 0;
03404 shape[2].x = 0;
03405 shape[2].y = -im;
03406 shape[3].x = 0;
03407 shape[3].y = im;
03408 SetMarkerType(4, 4, shape);
03409 } else if (fMarkerStyle == 3 || fMarkerStyle == 31) {
03410
03411 shape[0].x = -im;
03412 shape[0].y = 0;
03413 shape[1].x = im;
03414 shape[1].y = 0;
03415 shape[2].x = 0;
03416 shape[2].y = -im;
03417 shape[3].x = 0;
03418 shape[3].y = im;
03419 im = Int_t(0.707 * Float_t(im) + 0.5);
03420 shape[4].x = -im;
03421 shape[4].y = -im;
03422 shape[5].x = im;
03423 shape[5].y = im;
03424 shape[6].x = -im;
03425 shape[6].y = im;
03426 shape[7].x = im;
03427 shape[7].y = -im;
03428 SetMarkerType(4, 8, shape);
03429 } else if (fMarkerStyle == 4 || fMarkerStyle == 24) {
03430
03431 SetMarkerType(0, im * 2, shape);
03432 } else if (fMarkerStyle == 5) {
03433
03434 im = Int_t(0.707 * Float_t(im) + 0.5);
03435 shape[0].x = -im;
03436 shape[0].y = -im;
03437 shape[1].x = im;
03438 shape[1].y = im;
03439 shape[2].x = -im;
03440 shape[2].y = im;
03441 shape[3].x = im;
03442 shape[3].y = -im;
03443 SetMarkerType(4, 4, shape);
03444 } else if (fMarkerStyle == 6) {
03445
03446 shape[0].x = -1;
03447 shape[0].y = 0;
03448 shape[1].x = 1;
03449 shape[1].y = 0;
03450 shape[2].x = 0;
03451 shape[2].y = -1;
03452 shape[3].x = 0;
03453 shape[3].y = 1;
03454 SetMarkerType(4, 4, shape);
03455 } else if (fMarkerStyle == 7) {
03456
03457 shape[0].x = -1;
03458 shape[0].y = 1;
03459 shape[1].x = 1;
03460 shape[1].y = 1;
03461 shape[2].x = -1;
03462 shape[2].y = 0;
03463 shape[3].x = 1;
03464 shape[3].y = 0;
03465 shape[4].x = -1;
03466 shape[4].y = -1;
03467 shape[5].x = 1;
03468 shape[5].y = -1;
03469 SetMarkerType(4, 6, shape);
03470 } else if (fMarkerStyle == 8 || fMarkerStyle == 20) {
03471
03472 SetMarkerType(1, im * 2, shape);
03473 } else if (fMarkerStyle == 21) {
03474
03475 shape[0].x = -im;
03476 shape[0].y = -im;
03477 shape[1].x = im;
03478 shape[1].y = -im;
03479 shape[2].x = im;
03480 shape[2].y = im;
03481 shape[3].x = -im;
03482 shape[3].y = im;
03483 shape[4].x = -im;
03484 shape[4].y = -im;
03485 SetMarkerType(3, 5, shape);
03486 } else if (fMarkerStyle == 22) {
03487
03488 shape[0].x = -im;
03489 shape[0].y = im;
03490 shape[1].x = im;
03491 shape[1].y = im;
03492 shape[2].x = 0;
03493 shape[2].y = -im;
03494 shape[3].x = -im;
03495 shape[3].y = im;
03496 SetMarkerType(3, 4, shape);
03497 } else if (fMarkerStyle == 23) {
03498
03499 shape[0].x = 0;
03500 shape[0].y = im;
03501 shape[1].x = im;
03502 shape[1].y = -im;
03503 shape[2].x = -im;
03504 shape[2].y = -im;
03505 shape[3].x = 0;
03506 shape[3].y = im;
03507 SetMarkerType(3, 4, shape);
03508 } else if (fMarkerStyle == 25) {
03509
03510 shape[0].x = -im;
03511 shape[0].y = -im;
03512 shape[1].x = im;
03513 shape[1].y = -im;
03514 shape[2].x = im;
03515 shape[2].y = im;
03516 shape[3].x = -im;
03517 shape[3].y = im;
03518 shape[4].x = -im;
03519 shape[4].y = -im;
03520 SetMarkerType(2, 5, shape);
03521 } else if (fMarkerStyle == 26) {
03522
03523 shape[0].x = -im;
03524 shape[0].y = im;
03525 shape[1].x = im;
03526 shape[1].y = im;
03527 shape[2].x = 0;
03528 shape[2].y = -im;
03529 shape[3].x = -im;
03530 shape[3].y = im;
03531 SetMarkerType(2, 4, shape);
03532 } else if (fMarkerStyle == 27) {
03533
03534 Int_t imx = Int_t(2.66 * fMarkerSize + 0.5);
03535 shape[0].x = -imx;
03536 shape[0].y = 0;
03537 shape[1].x = 0;
03538 shape[1].y = -im;
03539 shape[2].x = imx;
03540 shape[2].y = 0;
03541 shape[3].x = 0;
03542 shape[3].y = im;
03543 shape[4].x = -imx;
03544 shape[4].y = 0;
03545 SetMarkerType(2, 5, shape);
03546 } else if (fMarkerStyle == 28) {
03547
03548 Int_t imx = Int_t(1.33 * fMarkerSize + 0.5);
03549 shape[0].x = -im;
03550 shape[0].y = -imx;
03551 shape[1].x = -imx;
03552 shape[1].y = -imx;
03553 shape[2].x = -imx;
03554 shape[2].y = -im;
03555 shape[3].x = imx;
03556 shape[3].y = -im;
03557 shape[4].x = imx;
03558 shape[4].y = -imx;
03559 shape[5].x = im;
03560 shape[5].y = -imx;
03561 shape[6].x = im;
03562 shape[6].y = imx;
03563 shape[7].x = imx;
03564 shape[7].y = imx;
03565 shape[8].x = imx;
03566 shape[8].y = im;
03567 shape[9].x = -imx;
03568 shape[9].y = im;
03569 shape[10].x = -imx;
03570 shape[10].y = imx;
03571 shape[11].x = -im;
03572 shape[11].y = imx;
03573 shape[12].x = -im;
03574 shape[12].y = -imx;
03575 SetMarkerType(2, 13, shape);
03576 } else if (fMarkerStyle == 29) {
03577
03578 Int_t im1 = Int_t(0.66 * fMarkerSize + 0.5);
03579 Int_t im2 = Int_t(2.00 * fMarkerSize + 0.5);
03580 Int_t im3 = Int_t(2.66 * fMarkerSize + 0.5);
03581 Int_t im4 = Int_t(1.33 * fMarkerSize + 0.5);
03582 shape[0].x = -im;
03583 shape[0].y = im4;
03584 shape[1].x = -im2;
03585 shape[1].y = -im1;
03586 shape[2].x = -im3;
03587 shape[2].y = -im;
03588 shape[3].x = 0;
03589 shape[3].y = -im2;
03590 shape[4].x = im3;
03591 shape[4].y = -im;
03592 shape[5].x = im2;
03593 shape[5].y = -im1;
03594 shape[6].x = im;
03595 shape[6].y = im4;
03596 shape[7].x = im4;
03597 shape[7].y = im4;
03598 shape[8].x = 0;
03599 shape[8].y = im;
03600 shape[9].x = -im4;
03601 shape[9].y = im4;
03602 shape[10].x = -im;
03603 shape[10].y = im4;
03604 SetMarkerType(3, 11, shape);
03605 } else if (fMarkerStyle == 30) {
03606
03607 Int_t im1 = Int_t(0.66 * fMarkerSize + 0.5);
03608 Int_t im2 = Int_t(2.00 * fMarkerSize + 0.5);
03609 Int_t im3 = Int_t(2.66 * fMarkerSize + 0.5);
03610 Int_t im4 = Int_t(1.33 * fMarkerSize + 0.5);
03611 shape[0].x = -im;
03612 shape[0].y = im4;
03613 shape[1].x = -im2;
03614 shape[1].y = -im1;
03615 shape[2].x = -im3;
03616 shape[2].y = -im;
03617 shape[3].x = 0;
03618 shape[3].y = -im2;
03619 shape[4].x = im3;
03620 shape[4].y = -im;
03621 shape[5].x = im2;
03622 shape[5].y = -im1;
03623 shape[6].x = im;
03624 shape[6].y = im4;
03625 shape[7].x = im4;
03626 shape[7].y = im4;
03627 shape[8].x = 0;
03628 shape[8].y = im;
03629 shape[9].x = -im4;
03630 shape[9].y = im4;
03631 shape[10].x = -im;
03632 shape[10].y = im4;
03633 SetMarkerType(2, 11, shape);
03634 } else if (fMarkerStyle == 32) {
03635
03636 shape[0].x = 0; shape[0].y = im;
03637 shape[1].x = im; shape[1].y = -im;
03638 shape[2].x = -im; shape[2].y = -im;
03639 shape[3].x = 0; shape[3].y = im;
03640 SetMarkerType(2,4,shape);
03641 } else if (fMarkerStyle == 33) {
03642
03643 Int_t imx = Int_t(2.66*fMarkerSize + 0.5);
03644 shape[0].x =-imx; shape[0].y = 0;
03645 shape[1].x = 0; shape[1].y = -im;
03646 shape[2].x = imx; shape[2].y = 0;
03647 shape[3].x = 0; shape[3].y = im;
03648 shape[4].x =-imx; shape[4].y = 0;
03649 SetMarkerType(3,5,shape);
03650 } else if (fMarkerStyle == 34) {
03651
03652 Int_t imx = Int_t(1.33*fMarkerSize + 0.5);
03653 shape[0].x = -im; shape[0].y =-imx;
03654 shape[1].x =-imx; shape[1].y =-imx;
03655 shape[2].x =-imx; shape[2].y = -im;
03656 shape[3].x = imx; shape[3].y = -im;
03657 shape[4].x = imx; shape[4].y =-imx;
03658 shape[5].x = im; shape[5].y =-imx;
03659 shape[6].x = im; shape[6].y = imx;
03660 shape[7].x = imx; shape[7].y = imx;
03661 shape[8].x = imx; shape[8].y = im;
03662 shape[9].x =-imx; shape[9].y = im;
03663 shape[10].x=-imx; shape[10].y= imx;
03664 shape[11].x= -im; shape[11].y= imx;
03665 shape[12].x= -im; shape[12].y=-imx;
03666 SetMarkerType(3,13,shape);
03667 } else {
03668
03669 SetMarkerType(0, 0, shape);
03670 }
03671 fMarkerStyleModified = kFALSE;
03672 }
03673
03674
03675 void TGWin32::SetOpacity(Int_t percent)
03676 {
03677
03678
03679
03680
03681
03682
03683 Int_t depth = gdk_visual_get_best_depth();
03684
03685 if (depth <= 8) return;
03686 if (percent == 0) return;
03687
03688
03689 ULong_t *orgcolors = 0, *tmpc = 0;
03690 Int_t maxcolors = 0, ncolors, ntmpc = 0;
03691
03692
03693 if (gCws->new_colors) {
03694 tmpc = gCws->new_colors;
03695 ntmpc = gCws->ncolors;
03696 }
03697
03698 GdkImage *image = gdk_image_get((GdkDrawable*)gCws->drawing, 0, 0,
03699 gCws->width, gCws->height);
03700
03701
03702 int x, y;
03703 for (y = 0; y < (int) gCws->height; y++) {
03704 for (x = 0; x < (int) gCws->width; x++) {
03705 ULong_t pixel = GetPixelImage((Drawable_t)image, x, y);
03706 CollectImageColors(pixel, orgcolors, ncolors, maxcolors);
03707 }
03708 }
03709 if (ncolors == 0) {
03710 gdk_image_unref(image);
03711 ::operator delete(orgcolors);
03712 return;
03713 }
03714
03715 MakeOpaqueColors(percent, orgcolors, ncolors);
03716
03717
03718 for (y = 0; y < (int) gCws->height; y++) {
03719 for (x = 0; x < (int) gCws->width; x++) {
03720 ULong_t pixel = GetPixelImage((Drawable_t)image, x, y);
03721 Int_t idx = FindColor(pixel, orgcolors, ncolors);
03722 PutPixel((Drawable_t)image, x, y, gCws->new_colors[idx]);
03723 }
03724 }
03725
03726
03727 gdk_draw_image(gCws->drawing, gGCpxmp, (GdkImage *)image,
03728 0, 0, 0, 0, gCws->width, gCws->height);
03729 GdiFlush();
03730
03731
03732 if (tmpc) {
03733 gdk_colors_free((GdkColormap *)fColormap, tmpc, ntmpc, 0);
03734 delete[]tmpc;
03735 }
03736 gdk_image_unref(image);
03737 ::operator delete(orgcolors);
03738 }
03739
03740
03741 void TGWin32::MakeOpaqueColors(Int_t percent, ULong_t *orgcolors, Int_t ncolors)
03742 {
03743
03744
03745
03746 Int_t ret;
03747 if (ncolors <= 0) return;
03748 GdkColor *xcol = new GdkColor[ncolors];
03749
03750 int i;
03751 for (i = 0; i < ncolors; i++) {
03752 xcol[i].pixel = orgcolors[i];
03753 xcol[i].red = xcol[i].green = xcol[i].blue = 0;
03754 }
03755
03756 GdkColorContext *cc;
03757 cc = gdk_color_context_new(gdk_visual_get_system(), (GdkColormap *)fColormap);
03758 gdk_color_context_query_colors(cc, xcol, ncolors);
03759 gdk_color_context_free(cc);
03760
03761 UShort_t add = percent * kBIGGEST_RGB_VALUE / 100;
03762
03763 Int_t val;
03764 for (i = 0; i < ncolors; i++) {
03765 val = xcol[i].red + add;
03766 if (val > kBIGGEST_RGB_VALUE) {
03767 val = kBIGGEST_RGB_VALUE;
03768 }
03769 xcol[i].red = (UShort_t) val;
03770 val = xcol[i].green + add;
03771 if (val > kBIGGEST_RGB_VALUE) {
03772 val = kBIGGEST_RGB_VALUE;
03773 }
03774 xcol[i].green = (UShort_t) val;
03775 val = xcol[i].blue + add;
03776 if (val > kBIGGEST_RGB_VALUE) {
03777 val = kBIGGEST_RGB_VALUE;
03778 }
03779 xcol[i].blue = (UShort_t) val;
03780
03781 ret = gdk_color_alloc((GdkColormap *)fColormap, &xcol[i]);
03782
03783 if (!ret) {
03784 Warning("MakeOpaqueColors",
03785 "failed to allocate color %hd, %hd, %hd", xcol[i].red,
03786 xcol[i].green, xcol[i].blue);
03787
03788 }
03789 }
03790
03791 gCws->new_colors = new ULong_t[ncolors];
03792 gCws->ncolors = ncolors;
03793
03794 for (i = 0; i < ncolors; i++) {
03795 gCws->new_colors[i] = xcol[i].pixel;
03796 }
03797
03798 delete []xcol;
03799 }
03800
03801
03802 Int_t TGWin32::FindColor(ULong_t pixel, ULong_t * orgcolors, Int_t ncolors)
03803 {
03804
03805
03806 for (int i = 0; i < ncolors; i++) {
03807 if (pixel == orgcolors[i]) return i;
03808 }
03809 Error("FindColor", "did not find color, should never happen!");
03810
03811 return 0;
03812 }
03813
03814
03815 void TGWin32::SetRGB(int cindex, float r, float g, float b)
03816 {
03817
03818
03819
03820
03821 GdkColor xcol;
03822
03823 if (fColormap && cindex >= 0) {
03824 xcol.red = (unsigned short) (r * kBIGGEST_RGB_VALUE);
03825 xcol.green = (unsigned short) (g * kBIGGEST_RGB_VALUE);
03826 xcol.blue = (unsigned short) (b * kBIGGEST_RGB_VALUE);
03827 xcol.pixel = RGB(xcol.red, xcol.green, xcol.blue);
03828
03829 XColor_t &col = GetColor(cindex);
03830 if (col.fDefined) {
03831
03832 if (col.color.red == xcol.red && col.color.green == xcol.green &&
03833 col.color.blue == xcol.blue)
03834 return;
03835 col.fDefined = kFALSE;
03836 gdk_colormap_free_colors((GdkColormap *) fColormap,
03837 (GdkColor *)&col, 1);
03838 }
03839
03840 Int_t ret = gdk_colormap_alloc_color(fColormap, &xcol, 1, 1);
03841 if (ret != 0) {
03842 col.fDefined = kTRUE;
03843 col.color.pixel = xcol.pixel;
03844 col.color.red = xcol.red;
03845 col.color.green = xcol.green;
03846 col.color.blue = xcol.blue;
03847 }
03848 }
03849 }
03850
03851
03852 void TGWin32::SetTextAlign(Short_t talign)
03853 {
03854
03855
03856
03857
03858 static Short_t current = 0;
03859 if (talign==current) return;
03860 current = talign;
03861
03862 Int_t txalh = talign / 10;
03863 Int_t txalv = talign % 10;
03864 fTextAlignH = txalh;
03865 fTextAlignV = txalv;
03866
03867 switch (txalh) {
03868
03869 case 0:
03870 case 1:
03871 switch (txalv) {
03872 case 1:
03873 fTextAlign = 7;
03874 break;
03875 case 2:
03876 fTextAlign = 4;
03877 break;
03878 case 3:
03879 fTextAlign = 1;
03880 break;
03881 }
03882 break;
03883 case 2:
03884 switch (txalv) {
03885 case 1:
03886 fTextAlign = 8;
03887 break;
03888 case 2:
03889 fTextAlign = 5;
03890 break;
03891 case 3:
03892 fTextAlign = 2;
03893 break;
03894 }
03895 break;
03896 case 3:
03897 switch (txalv) {
03898 case 1:
03899 fTextAlign = 9;
03900 break;
03901 case 2:
03902 fTextAlign = 6;
03903 break;
03904 case 3:
03905 fTextAlign = 3;
03906 break;
03907 }
03908 break;
03909 }
03910 TAttText::SetTextAlign(fTextAlign);
03911 }
03912
03913
03914 void TGWin32::SetTextColor(Color_t cindex)
03915 {
03916
03917
03918 static Int_t current = 0;
03919 GdkGCValues values;
03920 if ((cindex < 0) || (Int_t(cindex)==current)) return;
03921
03922 SetColor(gGCtext, Int_t(cindex));
03923 gdk_gc_get_values(gGCtext, &values);
03924 gdk_gc_set_foreground(gGCinvt, &values.background);
03925 gdk_gc_set_background(gGCinvt, &values.foreground);
03926 gdk_gc_set_background(gGCtext, (GdkColor *) & GetColor(0).color);
03927 current = Int_t(cindex);
03928 }
03929
03930
03931 void TGWin32::Sync(int mode)
03932 {
03933 }
03934
03935
03936 void TGWin32::UpdateWindow(int mode)
03937 {
03938
03939
03940
03941
03942
03943
03944
03945
03946 if (gCws && gCws->double_buffer) {
03947 gdk_window_copy_area(gCws->window, gGCpxmp, 0, 0,
03948 gCws->drawing, 0, 0, gCws->width, gCws->height);
03949 }
03950 Update(mode);
03951 }
03952
03953
03954 void TGWin32::Warp(int ix, int iy, Window_t id)
03955 {
03956
03957
03958
03959
03960
03961
03962 if (!id) return;
03963
03964 POINT cpt, tmp;
03965 HWND dw;
03966 if (!id)
03967 dw = (HWND) GDK_DRAWABLE_XID((GdkWindow *)gCws->window);
03968 else
03969 dw = (HWND) GDK_DRAWABLE_XID((GdkWindow *)id);
03970 GetCursorPos(&cpt);
03971 tmp.x = ix > 0 ? ix : cpt.x;
03972 tmp.y = iy > 0 ? iy : cpt.y;
03973 ClientToScreen(dw, &tmp);
03974 SetCursorPos(tmp.x, tmp.y);
03975 }
03976
03977
03978 void TGWin32::WritePixmap(int wid, unsigned int w, unsigned int h,
03979 char *pxname)
03980 {
03981
03982
03983
03984
03985
03986
03987 int wval, hval;
03988 wval = w;
03989 hval = h;
03990
03991 if (!fWindows) return;
03992 gTws = &fWindows[wid];
03993
03994 }
03995
03996
03997
03998
03999
04000
04001 static FILE *gGifFile;
04002 static GdkImage *gGifImage = 0;
04003
04004 extern "C" {
04005 int GIFquantize(UInt_t width, UInt_t height, Int_t * ncol, Byte_t * red,
04006 Byte_t * green, Byte_t * blue, Byte_t * outputBuf,
04007 Byte_t * outputCmap);
04008 long GIFencode(int Width, int Height, Int_t Ncol, Byte_t R[],
04009 Byte_t G[], Byte_t B[], Byte_t ScLine[],
04010 void (*get_scline) (int, int, Byte_t *),
04011 void (*pb) (Byte_t));
04012 int GIFdecode(Byte_t * GIFarr, Byte_t * PIXarr, int *Width, int *Height,
04013 int *Ncols, Byte_t * R, Byte_t * G, Byte_t * B);
04014 int GIFinfo(Byte_t * GIFarr, int *Width, int *Height, int *Ncols);
04015 }
04016
04017
04018
04019 static void GetPixel(int y, int width, Byte_t * scline)
04020 {
04021
04022
04023 for (int i = 0; i < width; i++) {
04024 scline[i] = Byte_t(GetPixelImage((Drawable_t)gGifImage, i, y));
04025 }
04026 }
04027
04028
04029 static void PutByte(Byte_t b)
04030 {
04031
04032
04033 if (ferror(gGifFile) == 0) fputc(b, gGifFile);
04034 }
04035
04036
04037 void TGWin32::ImgPickPalette(GdkImage * image, Int_t & ncol, Int_t * &R,
04038 Int_t * &G, Int_t * &B)
04039 {
04040
04041
04042
04043
04044
04045
04046
04047
04048 ULong_t *orgcolors = 0;
04049 Int_t maxcolors = 0, ncolors;
04050
04051
04052 int x, y;
04053 for (x = 0; x < (int) gCws->width; x++) {
04054 for (y = 0; y < (int) gCws->height; y++) {
04055 ULong_t pixel = GetPixelImage((Drawable_t)image, x, y);
04056 CollectImageColors(pixel, orgcolors, ncolors, maxcolors);
04057 }
04058 }
04059
04060
04061 GdkColor *xcol = new GdkColor[ncolors];
04062
04063 int i;
04064 for (i = 0; i < ncolors; i++) {
04065 xcol[i].pixel = orgcolors[i];
04066
04067 xcol[i].red = GetRValue(xcol[i].pixel);
04068 xcol[i].green = GetGValue(xcol[i].pixel);
04069 xcol[i].blue = GetBValue(xcol[i].pixel);
04070 }
04071
04072 GdkColorContext *cc;
04073 cc = gdk_color_context_new(gdk_visual_get_system(), (GdkColormap *)fColormap);
04074 gdk_color_context_query_colors(cc, xcol, ncolors);
04075 gdk_color_context_free(cc);
04076
04077
04078
04079 R = new Int_t[ncolors];
04080 G = new Int_t[ncolors];
04081 B = new Int_t[ncolors];
04082
04083 for (i = 0; i < ncolors; i++) {
04084 R[i] = xcol[i].red;
04085 G[i] = xcol[i].green;
04086 B[i] = xcol[i].blue;
04087 }
04088 ncol = ncolors;
04089
04090
04091 for (x = 0; x < (int) gCws->width; x++) {
04092 for (y = 0; y < (int) gCws->height; y++) {
04093 ULong_t pixel = GetPixelImage((Drawable_t)image, x, y);
04094 Int_t idx = FindColor(pixel, orgcolors, ncolors);
04095 PutPixel((Drawable_t)image, x, y, idx);
04096 }
04097 }
04098
04099
04100 delete[]xcol;
04101 ::operator delete(orgcolors);
04102 }
04103
04104
04105 Int_t TGWin32::WriteGIF(char *name)
04106 {
04107
04108
04109 Byte_t scline[2000], r[256], b[256], g[256];
04110 Int_t *R, *G, *B;
04111 Int_t ncol, maxcol, i;
04112
04113 if (gGifImage) {
04114 gdk_image_unref((GdkImage *)gGifImage);
04115 }
04116
04117 gGifImage = gdk_image_get((GdkDrawable*)gCws->drawing, 0, 0,
04118 gCws->width, gCws->height);
04119
04120 ImgPickPalette(gGifImage, ncol, R, G, B);
04121
04122 if (ncol > 256) {
04123
04124 Error("WriteGIF",
04125 "can not create GIF of image containing more than 256 colors");
04126 delete[]R;
04127 delete[]G;
04128 delete[]B;
04129 return 0;
04130 }
04131
04132 maxcol = 0;
04133 for (i = 0; i < ncol; i++) {
04134 if (maxcol < R[i]) maxcol = R[i];
04135 if (maxcol < G[i]) maxcol = G[i];
04136 if (maxcol < B[i]) maxcol = B[i];
04137 r[i] = 0;
04138 g[i] = 0;
04139 b[i] = 0;
04140 }
04141 if (maxcol != 0) {
04142 for (i = 0; i < ncol; i++) {
04143 r[i] = R[i] * 255 / maxcol;
04144 g[i] = G[i] * 255 / maxcol;
04145 b[i] = B[i] * 255 / maxcol;
04146 }
04147 }
04148
04149 gGifFile = fopen(name, "wb");
04150
04151 if (gGifFile) {
04152 GIFencode(gCws->width, gCws->height,
04153 ncol, r, g, b, scline, ::GetPixel, PutByte);
04154 fclose(gGifFile);
04155 i = 1;
04156 } else {
04157 Error("WriteGIF","cannot write file: %s",name);
04158 i = 0;
04159 }
04160 delete[]R;
04161 delete[]G;
04162 delete[]B;
04163
04164 return i;
04165 }
04166
04167
04168 void TGWin32::PutImage(int offset, int itran, int x0, int y0, int nx,
04169 int ny, int xmin, int ymin, int xmax, int ymax,
04170 unsigned char *image, Drawable_t wid)
04171 {
04172
04173
04174 const int MAX_SEGMENT = 20;
04175 int i, n, x, y, xcur, x1, x2, y1, y2;
04176 unsigned char *jimg, *jbase, icol;
04177 int nlines[256];
04178 GdkSegment lines[256][MAX_SEGMENT];
04179 GdkDrawable *id;
04180
04181 if (wid) {
04182 id = (GdkDrawable*)wid;
04183 } else {
04184 id = gCws->drawing;
04185 }
04186
04187 for (i = 0; i < 256; i++) nlines[i] = 0;
04188
04189 x1 = x0 + xmin;
04190 y1 = y0 + ny - ymax - 1;
04191 x2 = x0 + xmax;
04192 y2 = y0 + ny - ymin - 1;
04193 jbase = image + (ymin - 1) * nx + xmin;
04194
04195 for (y = y2; y >= y1; y--) {
04196 xcur = x1;
04197 jbase += nx;
04198 for (jimg = jbase, icol = *jimg++, x = x1 + 1; x <= x2; jimg++, x++) {
04199 if (icol != *jimg) {
04200 if (icol != itran) {
04201 n = nlines[icol]++;
04202 lines[icol][n].x1 = xcur;
04203 lines[icol][n].y1 = y;
04204 lines[icol][n].x2 = x - 1;
04205 lines[icol][n].y2 = y;
04206 if (nlines[icol] == MAX_SEGMENT) {
04207 SetColor(gGCline, (int) icol + offset);
04208 gdk_win32_draw_segments(id, (GdkGC *) gGCline,
04209 (GdkSegment *) &lines[icol][0], MAX_SEGMENT);
04210 nlines[icol] = 0;
04211 }
04212 }
04213 icol = *jimg;
04214 xcur = x;
04215 }
04216 }
04217 if (icol != itran) {
04218 n = nlines[icol]++;
04219 lines[icol][n].x1 = xcur;
04220 lines[icol][n].y1 = y;
04221 lines[icol][n].x2 = x - 1;
04222 lines[icol][n].y2 = y;
04223 if (nlines[icol] == MAX_SEGMENT) {
04224 SetColor(gGCline, (int) icol + offset);
04225 gdk_win32_draw_segments(id, (GdkGC *) gGCline,
04226 (GdkSegment *)&lines[icol][0], MAX_SEGMENT);
04227 nlines[icol] = 0;
04228 }
04229 }
04230 }
04231
04232 for (i = 0; i < 256; i++) {
04233 if (nlines[i] != 0) {
04234 SetColor(gGCline, i + offset);
04235 gdk_win32_draw_segments(id, (GdkGC *) gGCline,
04236 (GdkSegment *)&lines[icol][0], nlines[i]);
04237 }
04238 }
04239 }
04240
04241
04242 Pixmap_t TGWin32::ReadGIF(int x0, int y0, const char *file, Window_t id)
04243 {
04244
04245
04246
04247 FILE *fd;
04248 Seek_t filesize;
04249 unsigned char *GIFarr, *PIXarr, R[256], G[256], B[256], *j1, *j2, icol;
04250 int i, j, k, width, height, ncolor, irep, offset;
04251 float rr, gg, bb;
04252 Pixmap_t pic = 0;
04253
04254 fd = fopen(file, "r+b");
04255 if (!fd) {
04256 Error("ReadGIF", "unable to open GIF file");
04257 return pic;
04258 }
04259
04260 fseek(fd, 0L, 2);
04261 filesize = Seek_t(ftell(fd));
04262 fseek(fd, 0L, 0);
04263
04264 if (!(GIFarr = (unsigned char *) calloc(filesize + 256, 1))) {
04265 Error("ReadGIF", "unable to allocate array for gif");
04266 return pic;
04267 }
04268
04269 if (fread(GIFarr, filesize, 1, fd) != 1) {
04270 Error("ReadGIF", "GIF file read failed");
04271 return pic;
04272 }
04273
04274 irep = GIFinfo(GIFarr, &width, &height, &ncolor);
04275 if (irep != 0) {
04276 return pic;
04277 }
04278
04279 if (!(PIXarr = (unsigned char *) calloc((width * height), 1))) {
04280 Error("ReadGIF", "unable to allocate array for image");
04281 return pic;
04282 }
04283
04284 irep = GIFdecode(GIFarr, PIXarr, &width, &height, &ncolor, R, G, B);
04285 if (irep != 0) {
04286 return pic;
04287 }
04288
04289
04290 offset = 8;
04291
04292 for (i = 0; i < ncolor; i++) {
04293 rr = R[i] / 255.;
04294 gg = G[i] / 255.;
04295 bb = B[i] / 255.;
04296 j = i + offset;
04297 SetRGB(j, rr, gg, bb);
04298 }
04299
04300
04301
04302 for (i = 1; i <= height / 2; i++) {
04303 j1 = PIXarr + (i - 1) * width;
04304 j2 = PIXarr + (height - i) * width;
04305 for (k = 0; k < width; k++) {
04306 icol = *j1;
04307 *j1++ = *j2;
04308 *j2++ = icol;
04309 }
04310 }
04311
04312 if (id) pic = CreatePixmap(id, width, height);
04313 PutImage(offset, -1, x0, y0, width, height, 0, 0, width-1, height-1, PIXarr, pic);
04314
04315 if (pic) return pic;
04316 else if (gCws->drawing) return (Pixmap_t)gCws->drawing;
04317 else return 0;
04318 }
04319
04320
04321
04322 void TGWin32::MapWindow(Window_t id)
04323 {
04324
04325
04326 if (!id) return;
04327
04328 gdk_window_show((GdkWindow *)id);
04329 if ((GDK_DRAWABLE_TYPE((GdkWindow *)id) != GDK_WINDOW_TEMP) &&
04330 (GetParent(id) == GetDefaultRootWindow())) {
04331 HWND window = (HWND)GDK_DRAWABLE_XID((GdkWindow *)id);
04332 ::SetForegroundWindow(window);
04333 }
04334 }
04335
04336
04337 void TGWin32::MapSubwindows(Window_t id)
04338 {
04339
04340
04341 if (!id) return;
04342
04343 HWND wp;
04344 EnumChildWindows((HWND)GDK_DRAWABLE_XID((GdkWindow *)id),
04345 EnumChildProc, (LPARAM) NULL);
04346 }
04347
04348
04349 void TGWin32::MapRaised(Window_t id)
04350 {
04351
04352
04353 if (!id) return;
04354
04355 HWND hwnd = ::GetForegroundWindow();
04356 HWND window = (HWND)GDK_DRAWABLE_XID((GdkWindow *)id);
04357 gdk_window_show((GdkWindow *)id);
04358 if (GDK_DRAWABLE_TYPE((GdkWindow *)id) != GDK_WINDOW_TEMP) {
04359 ::BringWindowToTop(window);
04360 if (GDK_DRAWABLE_TYPE((GdkWindow *)id) != GDK_WINDOW_CHILD)
04361 ::SetForegroundWindow(window);
04362 }
04363
04364 if (gConsoleWindow && (hwnd == (HWND)gConsoleWindow)) {
04365 RECT r1, r2, r3;
04366 ::GetWindowRect((HWND)gConsoleWindow, &r1);
04367 HWND fore = ::GetForegroundWindow();
04368 ::GetWindowRect(fore, &r2);
04369 if (!::IntersectRect(&r3, &r2, &r1)) {
04370 ::SetForegroundWindow((HWND)gConsoleWindow);
04371 }
04372 }
04373 }
04374
04375
04376 void TGWin32::UnmapWindow(Window_t id)
04377 {
04378
04379
04380 if (!id) return;
04381
04382 gdk_window_hide((GdkWindow *) id);
04383 }
04384
04385
04386 void TGWin32::DestroyWindow(Window_t id)
04387 {
04388
04389
04390 if (!id) return;
04391
04392 gdk_window_destroy((GdkDrawable *) id, kTRUE);
04393 }
04394
04395
04396 void TGWin32::DestroySubwindows(Window_t id)
04397 {
04398
04399
04400 if (!id) return;
04401
04402 gdk_window_destroy((GdkDrawable *) id, kFALSE);
04403 }
04404
04405
04406 void TGWin32::RaiseWindow(Window_t id)
04407 {
04408
04409
04410 if (!id) return;
04411
04412 HWND window = (HWND)GDK_DRAWABLE_XID((GdkWindow *)id);
04413 if (GDK_DRAWABLE_TYPE((GdkWindow *)id) == GDK_WINDOW_TEMP) {
04414 ::SetWindowPos(window, HWND_TOPMOST, 0, 0, 0, 0,
04415 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
04416 }
04417 else {
04418 ::BringWindowToTop(window);
04419 if (GDK_DRAWABLE_TYPE((GdkWindow *)id) != GDK_WINDOW_CHILD)
04420 ::SetForegroundWindow(window);
04421 }
04422 }
04423
04424
04425 void TGWin32::LowerWindow(Window_t id)
04426 {
04427
04428
04429 if (!id) return;
04430
04431 HWND window = (HWND)GDK_DRAWABLE_XID((GdkWindow *)id);
04432 ::SetWindowPos(window, HWND_BOTTOM, 0, 0, 0, 0,
04433 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
04434 }
04435
04436
04437 void TGWin32::MoveWindow(Window_t id, Int_t x, Int_t y)
04438 {
04439
04440
04441 if (!id) return;
04442
04443 gdk_window_move((GdkDrawable *) id, x, y);
04444 }
04445
04446
04447 void TGWin32::MoveResizeWindow(Window_t id, Int_t x, Int_t y, UInt_t w,
04448 UInt_t h)
04449 {
04450
04451
04452 if (!id) return;
04453
04454 gdk_window_move_resize((GdkWindow *) id, x, y, w, h);
04455 }
04456
04457
04458 void TGWin32::ResizeWindow(Window_t id, UInt_t w, UInt_t h)
04459 {
04460
04461
04462 if (!id) return;
04463
04464 gdk_window_resize((GdkWindow *) id, w, h);
04465 }
04466
04467
04468 void TGWin32::IconifyWindow(Window_t id)
04469 {
04470
04471
04472 if (!id) return;
04473
04474 gdk_window_lower((GdkWindow *) id);
04475 ::CloseWindow((HWND)GDK_DRAWABLE_XID((GdkWindow *)id));
04476 }
04477
04478
04479 void TGWin32::ReparentWindow(Window_t id, Window_t pid, Int_t x, Int_t y)
04480 {
04481
04482
04483
04484 if (!id) return;
04485
04486 gdk_window_reparent((GdkWindow *)id, (GdkWindow *)pid, x, y);
04487 }
04488
04489
04490 void TGWin32::SetWindowBackground(Window_t id, ULong_t color)
04491 {
04492
04493
04494 if (!id) return;
04495
04496 GdkColor back;
04497 back.pixel = color;
04498 back.red = GetRValue(color);
04499 back.green = GetGValue(color);
04500 back.blue = GetBValue(color);
04501
04502 gdk_window_set_background((GdkWindow *) id, &back);
04503 }
04504
04505
04506 void TGWin32::SetWindowBackgroundPixmap(Window_t id, Pixmap_t pxm)
04507 {
04508
04509
04510 if (!id) return;
04511
04512 gdk_window_set_back_pixmap((GdkWindow *) id, (GdkPixmap *) pxm, 0);
04513 }
04514
04515
04516 Window_t TGWin32::CreateWindow(Window_t parent, Int_t x, Int_t y,
04517 UInt_t w, UInt_t h, UInt_t border,
04518 Int_t depth, UInt_t clss,
04519 void *visual, SetWindowAttributes_t * attr,
04520 UInt_t wtype)
04521 {
04522
04523
04524 GdkWMDecoration deco;
04525 GdkWindowAttr xattr;
04526 GdkWindow *newWin;
04527 GdkColor background_color;
04528 ULong_t xmask = 0;
04529 UInt_t xevmask;
04530
04531 if (attr) {
04532 MapSetWindowAttributes(attr, xmask, xattr);
04533 xattr.window_type = GDK_WINDOW_CHILD;
04534 if (wtype & kMainFrame) {
04535 xattr.window_type = GDK_WINDOW_TOPLEVEL;
04536 }
04537 if (wtype & kTransientFrame) {
04538 xattr.window_type = GDK_WINDOW_DIALOG;
04539 }
04540 if (wtype & kTempFrame) {
04541 xattr.window_type = GDK_WINDOW_TEMP;
04542 }
04543 newWin = gdk_window_new((GdkWindow *) parent, &xattr, xmask);
04544 } else {
04545 xattr.width = w;
04546 xattr.height = h;
04547 xattr.wclass = GDK_INPUT_OUTPUT;
04548 xattr.event_mask = 0L;
04549 xattr.event_mask |= GDK_EXPOSURE_MASK | GDK_STRUCTURE_MASK |
04550 GDK_PROPERTY_CHANGE_MASK;
04551
04552 if (x >= 0) {
04553 xattr.x = x;
04554 } else {
04555 xattr.x = -1.0 * x;
04556 }
04557 if (y >= 0) {
04558 xattr.y = y;
04559 } else {
04560 xattr.y = -1.0 * y;
04561 }
04562 xattr.colormap = gdk_colormap_get_system();
04563 xattr.cursor = NULL;
04564 xattr.override_redirect = TRUE;
04565 if ((xattr.y > 0) && (xattr.x > 0)) {
04566 xmask = GDK_WA_X | GDK_WA_Y | GDK_WA_COLORMAP |
04567 GDK_WA_WMCLASS | GDK_WA_NOREDIR;
04568 } else {
04569 xmask = GDK_WA_COLORMAP | GDK_WA_WMCLASS | GDK_WA_NOREDIR;
04570 }
04571 if (visual != NULL) {
04572 xattr.visual = (GdkVisual *) visual;
04573 xmask |= GDK_WA_VISUAL;
04574 } else {
04575 xattr.visual = gdk_visual_get_system();
04576 xmask |= GDK_WA_VISUAL;
04577 }
04578 xattr.window_type = GDK_WINDOW_CHILD;
04579 if (wtype & kMainFrame) {
04580 xattr.window_type = GDK_WINDOW_TOPLEVEL;
04581 }
04582 if (wtype & kTransientFrame) {
04583 xattr.window_type = GDK_WINDOW_DIALOG;
04584 }
04585 if (wtype & kTempFrame) {
04586 xattr.window_type = GDK_WINDOW_TEMP;
04587 }
04588 newWin = gdk_window_new((GdkWindow *) parent, &xattr, xmask);
04589 gdk_window_set_events(newWin, (GdkEventMask) 0L);
04590 }
04591 if (border > 0) {
04592 gdk_window_set_decorations(newWin,
04593 (GdkWMDecoration) GDK_DECOR_BORDER);
04594 }
04595 if (attr) {
04596 if ((attr->fMask & kWABackPixmap)) {
04597 if (attr->fBackgroundPixmap == kNone) {
04598 gdk_window_set_back_pixmap(newWin, (GdkPixmap *) GDK_NONE, 0);
04599 } else if (attr->fBackgroundPixmap == kParentRelative) {
04600 gdk_window_set_back_pixmap(newWin, (GdkPixmap *) GDK_NONE, 1);
04601 } else {
04602 gdk_window_set_back_pixmap(newWin,
04603 (GdkPixmap *) attr->
04604 fBackgroundPixmap, 0);
04605 }
04606 }
04607 if ((attr->fMask & kWABackPixel)) {
04608 background_color.pixel = attr->fBackgroundPixel;
04609 background_color.red = GetRValue(attr->fBackgroundPixel);
04610 background_color.green = GetGValue(attr->fBackgroundPixel);
04611 background_color.blue = GetBValue(attr->fBackgroundPixel);
04612 gdk_window_set_background(newWin, &background_color);
04613 }
04614 }
04615 if (!fUseSysPointers) {
04616 ::SetClassLong((HWND)GDK_DRAWABLE_XID(newWin), GCL_HCURSOR,
04617 (LONG)GDK_CURSOR_XID(fCursors[kPointer]));
04618 }
04619 return (Window_t) newWin;
04620 }
04621
04622
04623 void TGWin32::MapEventMask(UInt_t & emask, UInt_t & xemask, Bool_t tox)
04624 {
04625
04626
04627 if (tox) {
04628 Long_t lxemask = 0L;
04629 if ((emask & kKeyPressMask)) {
04630 lxemask |= GDK_KEY_PRESS_MASK;
04631 }
04632 if ((emask & kKeyReleaseMask)) {
04633 lxemask |= GDK_KEY_RELEASE_MASK;
04634 }
04635 if ((emask & kButtonPressMask)) {
04636 lxemask |= GDK_BUTTON_PRESS_MASK;
04637 }
04638 if ((emask & kButtonReleaseMask)) {
04639 lxemask |= GDK_BUTTON_RELEASE_MASK;
04640 }
04641 if ((emask & kPointerMotionMask)) {
04642 lxemask |= GDK_POINTER_MOTION_MASK;
04643 }
04644 if ((emask & kButtonMotionMask)) {
04645 lxemask |= GDK_BUTTON_MOTION_MASK;
04646 }
04647 if ((emask & kExposureMask)) {
04648 lxemask |= GDK_EXPOSURE_MASK;
04649 }
04650 if ((emask & kStructureNotifyMask)) {
04651 lxemask |= GDK_STRUCTURE_MASK;
04652 }
04653 if ((emask & kEnterWindowMask)) {
04654 lxemask |= GDK_ENTER_NOTIFY_MASK;
04655 }
04656 if ((emask & kLeaveWindowMask)) {
04657 lxemask |= GDK_LEAVE_NOTIFY_MASK;
04658 }
04659 if ((emask & kFocusChangeMask)) {
04660 lxemask |= GDK_FOCUS_CHANGE_MASK;
04661 }
04662 xemask = (UInt_t) lxemask;
04663 } else {
04664 emask = 0;
04665 if ((xemask & GDK_KEY_PRESS_MASK)) {
04666 emask |= kKeyPressMask;
04667 }
04668 if ((xemask & GDK_KEY_RELEASE_MASK)) {
04669 emask |= kKeyReleaseMask;
04670 }
04671 if ((xemask & GDK_BUTTON_PRESS_MASK)) {
04672 emask |= kButtonPressMask;
04673 }
04674 if ((xemask & GDK_BUTTON_RELEASE_MASK)) {
04675 emask |= kButtonReleaseMask;
04676 }
04677 if ((xemask & GDK_POINTER_MOTION_MASK)) {
04678 emask |= kPointerMotionMask;
04679 }
04680 if ((xemask & GDK_BUTTON_MOTION_MASK)) {
04681 emask |= kButtonMotionMask;
04682 }
04683 if ((xemask & GDK_EXPOSURE_MASK)) {
04684 emask |= kExposureMask;
04685 }
04686 if ((xemask & GDK_STRUCTURE_MASK)) {
04687 emask |= kStructureNotifyMask;
04688 }
04689 if ((xemask & GDK_ENTER_NOTIFY_MASK)) {
04690 emask |= kEnterWindowMask;
04691 }
04692 if ((xemask & GDK_LEAVE_NOTIFY_MASK)) {
04693 emask |= kLeaveWindowMask;
04694 }
04695 if ((xemask & GDK_FOCUS_CHANGE_MASK)) {
04696 emask |= kFocusChangeMask;
04697 }
04698 }
04699 }
04700
04701
04702 void TGWin32::MapSetWindowAttributes(SetWindowAttributes_t * attr,
04703 ULong_t & xmask,
04704 GdkWindowAttr & xattr)
04705 {
04706
04707
04708 Mask_t mask = attr->fMask;
04709 xmask = 0;
04710
04711 if ((mask & kWAOverrideRedirect)) {
04712 xmask |= GDK_WA_NOREDIR;
04713 xattr.override_redirect = attr->fOverrideRedirect;
04714 }
04715 if ((mask & kWAEventMask)) {
04716 UInt_t xmsk, msk = (UInt_t) attr->fEventMask;
04717 MapEventMask(msk, xmsk, kTRUE);
04718 xattr.event_mask = xmsk;
04719 }
04720 if ((mask & kWAColormap)) {
04721 xmask |= GDK_WA_COLORMAP;
04722 xattr.colormap = (GdkColormap *) attr->fColormap;
04723 }
04724 if ((mask & kWACursor)) {
04725 xmask |= GDK_WA_CURSOR;
04726 if (attr->fCursor != kNone) {
04727 xattr.cursor = (GdkCursor *) attr->fCursor;
04728 }
04729 }
04730 xattr.wclass = GDK_INPUT_OUTPUT;
04731 }
04732
04733
04734 void TGWin32::MapGCValues(GCValues_t & gval,
04735 ULong_t & xmask, GdkGCValues & xgval, Bool_t tox)
04736 {
04737
04738
04739
04740 if (tox) {
04741
04742 Mask_t mask = gval.fMask;
04743 xmask = 0;
04744
04745 if ((mask & kGCFunction)) {
04746 xmask |= GDK_GC_FUNCTION;
04747 switch (gval.fFunction) {
04748 case kGXclear:
04749 xgval.function = GDK_CLEAR;
04750 break;
04751 case kGXand:
04752 xgval.function = GDK_AND;
04753 break;
04754 case kGXandReverse:
04755 xgval.function = GDK_AND_REVERSE;
04756 break;
04757 case kGXcopy:
04758 xgval.function = GDK_COPY;
04759 break;
04760 case kGXandInverted:
04761 xgval.function = GDK_AND_INVERT;
04762 break;
04763 case kGXnoop:
04764 xgval.function = GDK_NOOP;
04765 break;
04766 case kGXxor:
04767 xgval.function = GDK_XOR;
04768 break;
04769 case kGXor:
04770 xgval.function = GDK_OR;
04771 break;
04772 case kGXequiv:
04773 xgval.function = GDK_EQUIV;
04774 break;
04775 case kGXinvert:
04776 xgval.function = GDK_INVERT;
04777 break;
04778 case kGXorReverse:
04779 xgval.function = GDK_OR_REVERSE;
04780 break;
04781 case kGXcopyInverted:
04782 xgval.function = GDK_COPY_INVERT;
04783 break;
04784 case kGXorInverted:
04785 xgval.function = GDK_OR_INVERT;
04786 break;
04787 case kGXnand:
04788 xgval.function = GDK_NAND;
04789 break;
04790 case kGXset:
04791 xgval.function = GDK_SET;
04792 break;
04793 }
04794 }
04795 if (mask & kGCSubwindowMode) {
04796 xmask |= GDK_GC_SUBWINDOW;
04797 if (gval.fSubwindowMode == kIncludeInferiors) {
04798 xgval.subwindow_mode = GDK_INCLUDE_INFERIORS;
04799 } else {
04800 xgval.subwindow_mode = GDK_CLIP_BY_CHILDREN;
04801 }
04802 }
04803 if (mask & kGCForeground) {
04804 xmask |= GDK_GC_FOREGROUND;
04805 xgval.foreground.pixel = gval.fForeground;
04806 xgval.foreground.red = GetRValue(gval.fForeground);
04807 xgval.foreground.green = GetGValue(gval.fForeground);
04808 xgval.foreground.blue = GetBValue(gval.fForeground);
04809 }
04810 if (mask & kGCBackground) {
04811 xmask |= GDK_GC_BACKGROUND;
04812 xgval.background.pixel = gval.fBackground;
04813 xgval.background.red = GetRValue(gval.fBackground);
04814 xgval.background.green = GetGValue(gval.fBackground);
04815 xgval.background.blue = GetBValue(gval.fBackground);
04816 }
04817 if (mask & kGCLineWidth) {
04818 xmask |= GDK_GC_LINE_WIDTH;
04819 xgval.line_width = gval.fLineWidth;
04820 }
04821 if (mask & kGCLineStyle) {
04822 xmask |= GDK_GC_LINE_STYLE;
04823 xgval.line_style = (GdkLineStyle) gval.fLineStyle;
04824 }
04825 if (mask & kGCCapStyle) {
04826 xmask |= GDK_GC_CAP_STYLE;
04827 xgval.cap_style = (GdkCapStyle) gval.fCapStyle;
04828 }
04829 if (mask & kGCJoinStyle) {
04830 xmask |= GDK_GC_JOIN_STYLE;
04831 xgval.join_style = (GdkJoinStyle) gval.fJoinStyle;
04832 }
04833 if ((mask & kGCFillStyle)) {
04834 xmask |= GDK_GC_FILL;
04835 xgval.fill = (GdkFill) gval.fFillStyle;
04836 }
04837 if ((mask & kGCTile)) {
04838 xmask |= GDK_GC_TILE;
04839 xgval.tile = (GdkPixmap *) gval.fTile;
04840 }
04841 if ((mask & kGCStipple)) {
04842 xmask |= GDK_GC_STIPPLE;
04843 xgval.stipple = (GdkPixmap *) gval.fStipple;
04844 }
04845 if ((mask & kGCTileStipXOrigin)) {
04846 xmask |= GDK_GC_TS_X_ORIGIN;
04847 xgval.ts_x_origin = gval.fTsXOrigin;
04848 }
04849 if ((mask & kGCTileStipYOrigin)) {
04850 xmask |= GDK_GC_TS_Y_ORIGIN;
04851 xgval.ts_y_origin = gval.fTsYOrigin;
04852 }
04853 if ((mask & kGCFont)) {
04854 xmask |= GDK_GC_FONT;
04855 xgval.font = (GdkFont *) gval.fFont;
04856 }
04857 if ((mask & kGCGraphicsExposures)) {
04858 xmask |= GDK_GC_EXPOSURES;
04859 xgval.graphics_exposures = gval.fGraphicsExposures;
04860 }
04861 if ((mask & kGCClipXOrigin)) {
04862 xmask |= GDK_GC_CLIP_X_ORIGIN;
04863 xgval.clip_x_origin = gval.fClipXOrigin;
04864 }
04865 if ((mask & kGCClipYOrigin)) {
04866 xmask |= GDK_GC_CLIP_Y_ORIGIN;
04867 xgval.clip_y_origin = gval.fClipYOrigin;
04868 }
04869 if ((mask & kGCClipMask)) {
04870 xmask |= GDK_GC_CLIP_MASK;
04871 xgval.clip_mask = (GdkPixmap *) gval.fClipMask;
04872 }
04873 } else {
04874
04875 Mask_t mask = 0;
04876
04877 if ((xmask & GDK_GC_FUNCTION)) {
04878 mask |= kGCFunction;
04879 gval.fFunction = (EGraphicsFunction) xgval.function;
04880 switch (xgval.function) {
04881 case GDK_CLEAR:
04882 gval.fFunction = kGXclear;
04883 break;
04884 case GDK_AND:
04885 gval.fFunction = kGXand;
04886 break;
04887 case GDK_AND_REVERSE:
04888 gval.fFunction = kGXandReverse;
04889 break;
04890 case GDK_COPY:
04891 gval.fFunction = kGXcopy;
04892 break;
04893 case GDK_AND_INVERT:
04894 gval.fFunction = kGXandInverted;
04895 break;
04896 case GDK_NOOP:
04897 gval.fFunction = kGXnoop;
04898 break;
04899 case GDK_XOR:
04900 gval.fFunction = kGXxor;
04901 break;
04902 case GDK_OR:
04903 gval.fFunction = kGXor;
04904 break;
04905 case GDK_EQUIV:
04906 gval.fFunction = kGXequiv;
04907 break;
04908 case GDK_INVERT:
04909 gval.fFunction = kGXinvert;
04910 break;
04911 case GDK_OR_REVERSE:
04912 gval.fFunction = kGXorReverse;
04913 break;
04914 case GDK_COPY_INVERT:
04915 gval.fFunction = kGXcopyInverted;
04916 break;
04917 case GDK_OR_INVERT:
04918 gval.fFunction = kGXorInverted;
04919 break;
04920 case GDK_NAND:
04921 gval.fFunction = kGXnand;
04922 break;
04923 case GDK_SET:
04924 gval.fFunction = kGXset;
04925 break;
04926 }
04927 }
04928 if (xmask & GDK_GC_SUBWINDOW) {
04929 mask |= kGCSubwindowMode;
04930 if (xgval.subwindow_mode == GDK_INCLUDE_INFERIORS)
04931 gval.fSubwindowMode = kIncludeInferiors;
04932 else
04933 gval.fSubwindowMode = kClipByChildren;
04934 }
04935 if ((xmask & GDK_GC_FOREGROUND)) {
04936 mask |= kGCForeground;
04937 gval.fForeground = xgval.foreground.pixel;
04938 }
04939 if ((xmask & GDK_GC_BACKGROUND)) {
04940 mask |= kGCBackground;
04941 gval.fBackground = xgval.background.pixel;
04942 }
04943 if ((xmask & GDK_GC_LINE_WIDTH)) {
04944 mask |= kGCLineWidth;
04945 gval.fLineWidth = xgval.line_width;
04946 }
04947 if ((xmask & GDK_GC_LINE_STYLE)) {
04948 mask |= kGCLineStyle;
04949 gval.fLineStyle = xgval.line_style;
04950 }
04951 if ((xmask & GDK_GC_CAP_STYLE)) {
04952 mask |= kGCCapStyle;
04953 gval.fCapStyle = xgval.cap_style;
04954 }
04955 if ((xmask & GDK_GC_JOIN_STYLE)) {
04956 mask |= kGCJoinStyle;
04957 gval.fJoinStyle = xgval.join_style;
04958 }
04959 if ((xmask & GDK_GC_FILL)) {
04960 mask |= kGCFillStyle;
04961 gval.fFillStyle = xgval.fill;
04962 }
04963 if ((xmask & GDK_GC_TILE)) {
04964 mask |= kGCTile;
04965 gval.fTile = (Pixmap_t) xgval.tile;
04966 }
04967 if ((xmask & GDK_GC_STIPPLE)) {
04968 mask |= kGCStipple;
04969 gval.fStipple = (Pixmap_t) xgval.stipple;
04970 }
04971 if ((xmask & GDK_GC_TS_X_ORIGIN)) {
04972 mask |= kGCTileStipXOrigin;
04973 gval.fTsXOrigin = xgval.ts_x_origin;
04974 }
04975 if ((xmask & GDK_GC_TS_Y_ORIGIN)) {
04976 mask |= kGCTileStipYOrigin;
04977 gval.fTsYOrigin = xgval.ts_y_origin;
04978 }
04979 if ((xmask & GDK_GC_FONT)) {
04980 mask |= kGCFont;
04981 gval.fFont = (FontH_t) xgval.font;
04982 }
04983 if ((xmask & GDK_GC_EXPOSURES)) {
04984 mask |= kGCGraphicsExposures;
04985 gval.fGraphicsExposures = (Bool_t) xgval.graphics_exposures;
04986 }
04987 if ((xmask & GDK_GC_CLIP_X_ORIGIN)) {
04988 mask |= kGCClipXOrigin;
04989 gval.fClipXOrigin = xgval.clip_x_origin;
04990 }
04991 if ((xmask & GDK_GC_CLIP_Y_ORIGIN)) {
04992 mask |= kGCClipYOrigin;
04993 gval.fClipYOrigin = xgval.clip_y_origin;
04994 }
04995 if ((xmask & GDK_GC_CLIP_MASK)) {
04996 mask |= kGCClipMask;
04997 gval.fClipMask = (Pixmap_t) xgval.clip_mask;
04998 }
04999 gval.fMask = mask;
05000 }
05001 }
05002
05003
05004 void TGWin32::GetWindowAttributes(Window_t id, WindowAttributes_t & attr)
05005 {
05006
05007
05008 if (!id) return;
05009
05010 GdkWindowAttr xattr;
05011 RECT rcClient, rcWind;
05012 ::GetClientRect((HWND)GDK_DRAWABLE_XID((GdkWindow *) id), &rcClient);
05013 ::GetWindowRect((HWND)GDK_DRAWABLE_XID((GdkWindow *) id), &rcWind);
05014
05015 gdk_window_get_geometry((GdkWindow *) id, &attr.fX, &attr.fY,
05016 &attr.fWidth, &attr.fHeight, &attr.fDepth);
05017 attr.fX = ((rcWind.right - rcWind.left) - rcClient.right) / 2;
05018 attr.fY = ((rcWind.bottom - rcWind.top) - rcClient.bottom) - attr.fX;
05019
05020 attr.fRoot = (Window_t) GDK_ROOT_PARENT();
05021 attr.fColormap = (Colormap_t) gdk_window_get_colormap((GdkWindow *) id);
05022 attr.fBorderWidth = 0;
05023 attr.fVisual = gdk_window_get_visual((GdkWindow *) id);
05024 attr.fClass = kInputOutput;
05025 attr.fBackingStore = kNotUseful;
05026 attr.fSaveUnder = kFALSE;
05027 attr.fMapInstalled = kTRUE;
05028 attr.fOverrideRedirect = kFALSE;
05029
05030 if (!gdk_window_is_visible((GdkWindow *) id)) {
05031 attr.fMapState = kIsUnmapped;
05032 } else if (!gdk_window_is_viewable((GdkWindow *) id)) {
05033 attr.fMapState = kIsUnviewable;
05034 } else {
05035 attr.fMapState = kIsViewable;
05036 }
05037
05038 UInt_t tmp_mask = (UInt_t)gdk_window_get_events((GdkWindow *) id);
05039 UInt_t evmask;
05040 MapEventMask(evmask, tmp_mask, kFALSE);
05041
05042 attr.fYourEventMask = evmask;
05043 }
05044
05045
05046 Display_t TGWin32::GetDisplay() const
05047 {
05048
05049
05050 return 0;
05051 }
05052
05053
05054 Int_t TGWin32::GetDepth() const
05055 {
05056
05057
05058 return gdk_visual_get_best_depth();
05059 }
05060
05061
05062 Atom_t TGWin32::InternAtom(const char *atom_name, Bool_t only_if_exist)
05063 {
05064
05065
05066
05067
05068 GdkAtom a = gdk_atom_intern((const gchar *) atom_name, only_if_exist);
05069
05070 if (a == None) return kNone;
05071 return (Atom_t) a;
05072 }
05073
05074
05075 Window_t TGWin32::GetDefaultRootWindow() const
05076 {
05077
05078
05079
05080 return (Window_t) GDK_ROOT_PARENT();
05081 }
05082
05083
05084 Window_t TGWin32::GetParent(Window_t id) const
05085 {
05086
05087
05088 if (!id) return (Window_t)0;
05089
05090 return (Window_t)gdk_window_get_parent((GdkWindow *) id);
05091 }
05092
05093
05094 FontStruct_t TGWin32::LoadQueryFont(const char *font_name)
05095 {
05096
05097
05098
05099
05100 char family[100], weight[32], slant[32], fontname[256];
05101 Int_t n1, pixel, numfields;
05102
05103 numfields = sscanf(font_name, "%s -%d%n", family, &pixel, &n1);
05104 if (numfields == 2) {
05105 sprintf(weight,"medium");
05106 if (strstr(font_name, "bold"))
05107 sprintf(weight,"bold");
05108 sprintf(slant,"r");
05109 if (strstr(font_name, "italic"))
05110 sprintf(slant,"i");
05111 sprintf(fontname, "-*-%s-%s-%s-*-*-%d-*-*-*-*-*-iso8859-1",
05112 family, weight, slant, pixel);
05113 }
05114 else
05115 sprintf(fontname, "%s", font_name);
05116 return (FontStruct_t) gdk_font_load(fontname);
05117 }
05118
05119
05120 FontH_t TGWin32::GetFontHandle(FontStruct_t fs)
05121 {
05122
05123
05124 if (fs) {
05125 return (FontH_t)gdk_font_ref((GdkFont *) fs);
05126 }
05127 return 0;
05128 }
05129
05130
05131 void TGWin32::DeleteFont(FontStruct_t fs)
05132 {
05133
05134
05135 gdk_font_unref((GdkFont *) fs);
05136 }
05137
05138
05139 GContext_t TGWin32::CreateGC(Drawable_t id, GCValues_t *gval)
05140 {
05141
05142
05143
05144 if (!id) return (GContext_t)0;
05145
05146 GdkGCValues xgval;
05147 ULong_t xmask = 0;
05148
05149 if (gval) MapGCValues(*gval, xmask, xgval, kTRUE);
05150
05151 xgval.subwindow_mode = GDK_CLIP_BY_CHILDREN;
05152
05153 GdkGC *gc = gdk_gc_new_with_values((GdkDrawable *) id,
05154 &xgval, (GdkGCValuesMask)xmask);
05155 return (GContext_t) gc;
05156 }
05157
05158
05159 void TGWin32::ChangeGC(GContext_t gc, GCValues_t * gval)
05160 {
05161
05162
05163 GdkGCValues xgval;
05164 ULong_t xmask = 0;
05165 Mask_t mask = 0;
05166
05167 if (gval) {
05168 mask = gval->fMask;
05169 MapGCValues(*gval, xmask, xgval, kTRUE);
05170 }
05171 if (mask & kGCForeground) {
05172 gdk_gc_set_foreground((GdkGC *) gc, &xgval.foreground);
05173 }
05174 if (mask & kGCBackground) {
05175 gdk_gc_set_background((GdkGC *) gc, &xgval.background);
05176 }
05177 if (mask & kGCFont) {
05178 gdk_gc_set_font((GdkGC *) gc, xgval.font);
05179 }
05180 if (mask & kGCFunction) {
05181 gdk_gc_set_function((GdkGC *) gc, xgval.function);
05182 }
05183 if (mask & kGCFillStyle) {
05184 gdk_gc_set_fill((GdkGC *) gc, xgval.fill);
05185 }
05186 if (mask & kGCTile) {
05187 gdk_gc_set_tile((GdkGC *) gc, xgval.tile);
05188 }
05189 if (mask & kGCStipple) {
05190 gdk_gc_set_stipple((GdkGC *) gc, xgval.stipple);
05191 }
05192 if ((mask & kGCTileStipXOrigin) || (mask & kGCTileStipYOrigin)) {
05193 gdk_gc_set_ts_origin((GdkGC *) gc, xgval.ts_x_origin,
05194 xgval.ts_y_origin);
05195 }
05196 if ((mask & kGCClipXOrigin) || (mask & kGCClipYOrigin)) {
05197 gdk_gc_set_clip_origin((GdkGC *) gc, xgval.clip_x_origin,
05198 xgval.clip_y_origin);
05199 }
05200 if (mask & kGCClipMask) {
05201 gdk_gc_set_clip_mask((GdkGC *) gc, xgval.clip_mask);
05202 }
05203 if (mask & kGCGraphicsExposures) {
05204 gdk_gc_set_exposures((GdkGC *) gc, xgval.graphics_exposures);
05205 }
05206 if (mask & kGCLineWidth) {
05207 gdk_gc_set_values((GdkGC *) gc, &xgval, GDK_GC_LINE_WIDTH);
05208 }
05209 if (mask & kGCLineStyle) {
05210 gdk_gc_set_values((GdkGC *) gc, &xgval, GDK_GC_LINE_STYLE);
05211 }
05212 if (mask & kGCCapStyle) {
05213 gdk_gc_set_values((GdkGC *) gc, &xgval, GDK_GC_CAP_STYLE);
05214 }
05215 if (mask & kGCJoinStyle) {
05216 gdk_gc_set_values((GdkGC *) gc, &xgval, GDK_GC_JOIN_STYLE);
05217 }
05218 if (mask & kGCSubwindowMode) {
05219 gdk_gc_set_subwindow((GdkGC *) gc, xgval.subwindow_mode);
05220 }
05221 }
05222
05223
05224 void TGWin32::CopyGC(GContext_t org, GContext_t dest, Mask_t mask)
05225 {
05226
05227
05228
05229 GCValues_t gval;
05230 GdkGCValues xgval;
05231 ULong_t xmask;
05232
05233 if (!mask) {
05234
05235 mask = (Mask_t) - 1;
05236 }
05237
05238 gval.fMask = mask;
05239 MapGCValues(gval, xmask, xgval, kTRUE);
05240
05241 gdk_gc_copy((GdkGC *) dest, (GdkGC *) org);
05242 }
05243
05244
05245 void TGWin32::DeleteGC(GContext_t gc)
05246 {
05247
05248
05249 gdk_gc_unref((GdkGC *) gc);
05250 }
05251
05252
05253 Cursor_t TGWin32::CreateCursor(ECursor cursor)
05254 {
05255
05256
05257 return (Cursor_t) fCursors[cursor];
05258 }
05259
05260
05261 Pixmap_t TGWin32::CreatePixmap(Drawable_t id, UInt_t w, UInt_t h)
05262 {
05263
05264
05265
05266 GdkWindow *wid = (GdkWindow *)id;
05267 if (!id) wid = GDK_ROOT_PARENT();
05268
05269 return (Pixmap_t) gdk_pixmap_new(wid, w, h, gdk_visual_get_best_depth());
05270 }
05271
05272
05273 Pixmap_t TGWin32::CreatePixmap(Drawable_t id, const char *bitmap,
05274 UInt_t width, UInt_t height,
05275 ULong_t forecolor, ULong_t backcolor,
05276 Int_t depth)
05277 {
05278
05279
05280
05281 GdkColor fore, back;
05282 fore.pixel = forecolor;
05283 fore.red = GetRValue(forecolor);
05284 fore.green = GetGValue(forecolor);
05285 fore.blue = GetBValue(forecolor);
05286
05287 back.pixel = backcolor;
05288 back.red = GetRValue(backcolor);
05289 back.green = GetGValue(backcolor);
05290 back.blue = GetBValue(backcolor);
05291
05292 GdkWindow *wid = (GdkWindow *)id;
05293 if (!id) wid = GDK_ROOT_PARENT();
05294
05295 return (Pixmap_t) gdk_pixmap_create_from_data(wid, (char *) bitmap, width,
05296 height, depth, &fore, &back);
05297 }
05298
05299
05300 Pixmap_t TGWin32::CreateBitmap(Drawable_t id, const char *bitmap,
05301 UInt_t width, UInt_t height)
05302 {
05303
05304
05305 GdkWindow *wid = (GdkWindow *)id;
05306 if (!id) wid = GDK_ROOT_PARENT();
05307
05308 Pixmap_t ret = (Pixmap_t) gdk_bitmap_create_from_data(wid,
05309 (char *)bitmap, width, height);
05310 return ret;
05311 }
05312
05313
05314 void TGWin32::DeletePixmap(Pixmap_t pmap)
05315 {
05316
05317
05318 gdk_pixmap_unref((GdkPixmap *) pmap);
05319 }
05320
05321
05322 Bool_t TGWin32::CreatePictureFromFile(Drawable_t id, const char *filename,
05323 Pixmap_t & pict,
05324 Pixmap_t & pict_mask,
05325 PictureAttributes_t & attr)
05326 {
05327
05328
05329
05330
05331 GdkBitmap *gdk_pixmap_mask;
05332 if (strstr(filename, ".xpm") || strstr(filename, ".XPM")) {
05333 GdkWindow *wid = (GdkWindow *)id;
05334 if (!id) wid = GDK_ROOT_PARENT();
05335
05336 pict = (Pixmap_t) gdk_pixmap_create_from_xpm(wid, &gdk_pixmap_mask, 0,
05337 filename);
05338 pict_mask = (Pixmap_t) gdk_pixmap_mask;
05339 } else if (strstr(filename, ".gif") || strstr(filename, ".GIF")) {
05340 pict = ReadGIF(0, 0, filename, id);
05341 pict_mask = kNone;
05342 }
05343
05344 gdk_drawable_get_size((GdkPixmap *) pict, (int *) &attr.fWidth,
05345 (int *) &attr.fHeight);
05346 if (pict) {
05347 return kTRUE;
05348 }
05349 if (pict_mask) {
05350 pict_mask = kNone;
05351 }
05352 return kFALSE;
05353 }
05354
05355
05356 Bool_t TGWin32::CreatePictureFromData(Drawable_t id, char **data,
05357 Pixmap_t & pict,
05358 Pixmap_t & pict_mask,
05359 PictureAttributes_t & attr)
05360 {
05361
05362
05363
05364
05365 GdkBitmap *gdk_pixmap_mask;
05366 GdkWindow *wid = (GdkWindow *)id;
05367 if (!id) wid = GDK_ROOT_PARENT();
05368
05369 pict = (Pixmap_t) gdk_pixmap_create_from_xpm_d(wid, &gdk_pixmap_mask, 0,
05370 data);
05371 pict_mask = (Pixmap_t) gdk_pixmap_mask;
05372
05373 if (pict) {
05374 return kTRUE;
05375 }
05376 if (pict_mask) {
05377 pict_mask = kNone;
05378 }
05379 return kFALSE;
05380 }
05381
05382
05383 Bool_t TGWin32::ReadPictureDataFromFile(const char *filename, char ***ret_data)
05384 {
05385
05386
05387
05388 Bool_t ret = kFALSE;
05389 GdkPixmap *pxm = gdk_pixmap_create_from_xpm(NULL, NULL, NULL, filename);
05390 ret_data = 0;
05391
05392 if (pxm==NULL) return kFALSE;
05393
05394 HBITMAP hbm = (HBITMAP)GDK_DRAWABLE_XID(pxm);
05395 BITMAP bitmap;
05396
05397 ret = ::GetObject(hbm, sizeof(HBITMAP), (LPVOID)&bitmap);
05398 ret_data = (char ***)&bitmap.bmBits;
05399 gdk_pixmap_unref(pxm);
05400 return ret;
05401 }
05402
05403
05404 void TGWin32::DeletePictureData(void *data)
05405 {
05406
05407
05408 free(data);
05409 }
05410
05411
05412 void TGWin32::SetDashes(GContext_t gc, Int_t offset, const char *dash_list,
05413 Int_t n)
05414 {
05415
05416
05417
05418
05419 int i;
05420 gint8 dashes[32];
05421 for (i = 0; i < n; i++) {
05422 dashes[i] = (gint8) dash_list[i];
05423 }
05424 for (i = n; i < 32; i++) {
05425 dashes[i] = (gint8) 0;
05426 }
05427
05428 gdk_gc_set_dashes((GdkGC *) gc, offset, dashes, n);
05429 }
05430
05431
05432 void TGWin32::MapColorStruct(ColorStruct_t * color, GdkColor & xcolor)
05433 {
05434
05435
05436 xcolor.pixel = color->fPixel;
05437 xcolor.red = color->fRed;
05438 xcolor.green = color->fGreen;
05439 xcolor.blue = color->fBlue;
05440 }
05441
05442
05443 Bool_t TGWin32::ParseColor(Colormap_t cmap, const char *cname,
05444 ColorStruct_t & color)
05445 {
05446
05447
05448
05449
05450
05451
05452 GdkColor xc;
05453
05454 if (gdk_color_parse((char *)cname, &xc)) {
05455 color.fPixel = xc.pixel = RGB(xc.red, xc.green, xc.blue);
05456 color.fRed = xc.red;
05457 color.fGreen = xc.green;
05458 color.fBlue = xc.blue;
05459 return kTRUE;
05460 }
05461 return kFALSE;
05462 }
05463
05464
05465 Bool_t TGWin32::AllocColor(Colormap_t cmap, ColorStruct_t & color)
05466 {
05467
05468
05469
05470
05471 int status;
05472 GdkColor xc;
05473
05474 xc.red = color.fRed;
05475 xc.green = color.fGreen;
05476 xc.blue = color.fBlue;
05477
05478 status = gdk_colormap_alloc_color((GdkColormap *) cmap, &xc, FALSE, TRUE);
05479 color.fPixel = xc.pixel;
05480
05481 return kTRUE;
05482 }
05483
05484
05485 void TGWin32::QueryColor(Colormap_t cmap, ColorStruct_t & color)
05486 {
05487
05488
05489
05490
05491 GdkColor xc;
05492 xc.pixel = color.fPixel;
05493
05494 GdkColorContext *cc = gdk_color_context_new(gdk_visual_get_system(), fColormap);
05495 gdk_color_context_query_color(cc, &xc);
05496 gdk_color_context_free(cc);
05497
05498 color.fPixel = xc.pixel;
05499 color.fRed = xc.red;
05500 color.fGreen = xc.green;
05501 color.fBlue = xc.blue;
05502 }
05503
05504
05505 void TGWin32::FreeColor(Colormap_t cmap, ULong_t pixel)
05506 {
05507
05508
05509
05510 }
05511
05512
05513 Bool_t TGWin32::CheckEvent(Window_t id, EGEventType type, Event_t & ev)
05514 {
05515
05516
05517
05518
05519 if (!id) return kFALSE;
05520
05521 Event_t tev;
05522 GdkEvent xev;
05523
05524 tev.fType = type;
05525 tev.fWindow = (Window_t) id;
05526 tev.fTime = 0;
05527 tev.fX = tev.fY = 0;
05528 tev.fXRoot = tev.fYRoot = 0;
05529 tev.fCode = 0;
05530 tev.fState = 0;
05531 tev.fWidth = tev.fHeight = 0;
05532 tev.fCount = 0;
05533 tev.fSendEvent = kFALSE;
05534 tev.fHandle = 0;
05535 tev.fFormat = 0;
05536 tev.fUser[0] = tev.fUser[1] = tev.fUser[2] = tev.fUser[3] = tev.fUser[4] = 0L;
05537
05538 TGWin32MainThread::LockMSG();
05539 MapEvent(tev, xev, kTRUE);
05540 Bool_t r = gdk_check_typed_window_event((GdkWindow *) id, xev.type, &xev);
05541
05542 if (r) MapEvent(ev, xev, kFALSE);
05543 TGWin32MainThread::UnlockMSG();
05544
05545 return r ? kTRUE : kFALSE;
05546 }
05547
05548
05549 void TGWin32::SendEvent(Window_t id, Event_t * ev)
05550 {
05551
05552
05553 if (!ev || !id) return;
05554
05555 TGWin32MainThread::LockMSG();
05556 GdkEvent xev;
05557 MapEvent(*ev, xev, kTRUE);
05558 gdk_event_put(&xev);
05559 TGWin32MainThread::UnlockMSG();
05560 }
05561
05562
05563 Int_t TGWin32::EventsPending()
05564 {
05565
05566
05567 Int_t ret;
05568
05569 TGWin32MainThread::LockMSG();
05570 ret = (Int_t)gdk_event_queue_find_first();
05571 TGWin32MainThread::UnlockMSG();
05572
05573 return ret;
05574 }
05575
05576
05577 void TGWin32::NextEvent(Event_t & event)
05578 {
05579
05580
05581
05582
05583 TGWin32MainThread::LockMSG();
05584 GdkEvent *xev = gdk_event_unqueue();
05585
05586
05587 event.fType = kOtherEvent;
05588 if (xev == NULL) {
05589 TGWin32MainThread::UnlockMSG();
05590 return;
05591 }
05592 MapEvent(event, *xev, kFALSE);
05593 gdk_event_free (xev);
05594 TGWin32MainThread::UnlockMSG();
05595 }
05596
05597
05598 void TGWin32::MapModifierState(UInt_t & state, UInt_t & xstate, Bool_t tox)
05599 {
05600
05601
05602 if (tox) {
05603 xstate = state;
05604 if (state & kAnyModifier) {
05605 xstate = GDK_MODIFIER_MASK;
05606 }
05607 } else {
05608 state = xstate;
05609 }
05610 }
05611
05612 static void _set_event_time(GdkEvent &event, UInt_t time)
05613 {
05614
05615
05616 switch (event.type) {
05617 case GDK_MOTION_NOTIFY:
05618 event.motion.time = time;
05619 case GDK_BUTTON_PRESS:
05620 case GDK_2BUTTON_PRESS:
05621 case GDK_3BUTTON_PRESS:
05622 case GDK_BUTTON_RELEASE:
05623 case GDK_SCROLL:
05624 event.button.time = time;
05625 case GDK_KEY_PRESS:
05626 case GDK_KEY_RELEASE:
05627 event.key.time = time;
05628 case GDK_ENTER_NOTIFY:
05629 case GDK_LEAVE_NOTIFY:
05630 event.crossing.time = time;
05631 case GDK_PROPERTY_NOTIFY:
05632 event.property.time = time;
05633 case GDK_SELECTION_CLEAR:
05634 case GDK_SELECTION_REQUEST:
05635 case GDK_SELECTION_NOTIFY:
05636 event.selection.time = time;
05637 case GDK_PROXIMITY_IN:
05638 case GDK_PROXIMITY_OUT:
05639 event.proximity.time = time;
05640 case GDK_DRAG_ENTER:
05641 case GDK_DRAG_LEAVE:
05642 case GDK_DRAG_MOTION:
05643 case GDK_DRAG_STATUS:
05644 case GDK_DROP_START:
05645 case GDK_DROP_FINISHED:
05646 event.dnd.time = time;
05647 default:
05648 break;
05649 }
05650 }
05651
05652
05653 void TGWin32::MapEvent(Event_t & ev, GdkEvent & xev, Bool_t tox)
05654 {
05655
05656
05657
05658 if (tox) {
05659
05660 xev.type = GDK_NOTHING;
05661 if (ev.fType == kGKeyPress)
05662 xev.type = GDK_KEY_PRESS;
05663 if (ev.fType == kKeyRelease)
05664 xev.type = GDK_KEY_RELEASE;
05665 if (ev.fType == kButtonPress)
05666 xev.type = GDK_BUTTON_PRESS;
05667 if (ev.fType == kButtonRelease)
05668 xev.type = GDK_BUTTON_RELEASE;
05669 if (ev.fType == kMotionNotify)
05670 xev.type = GDK_MOTION_NOTIFY;
05671 if (ev.fType == kEnterNotify)
05672 xev.type = GDK_ENTER_NOTIFY;
05673 if (ev.fType == kLeaveNotify)
05674 xev.type = GDK_LEAVE_NOTIFY;
05675 if (ev.fType == kExpose)
05676 xev.type = GDK_EXPOSE;
05677 if (ev.fType == kConfigureNotify)
05678 xev.type = GDK_CONFIGURE;
05679 if (ev.fType == kMapNotify)
05680 xev.type = GDK_MAP;
05681 if (ev.fType == kUnmapNotify)
05682 xev.type = GDK_UNMAP;
05683 if (ev.fType == kDestroyNotify)
05684 xev.type = GDK_DESTROY;
05685 if (ev.fType == kClientMessage)
05686 xev.type = GDK_CLIENT_EVENT;
05687 if (ev.fType == kSelectionClear)
05688 xev.type = GDK_SELECTION_CLEAR;
05689 if (ev.fType == kSelectionRequest)
05690 xev.type = GDK_SELECTION_REQUEST;
05691 if (ev.fType == kSelectionNotify)
05692 xev.type = GDK_SELECTION_NOTIFY;
05693
05694 xev.any.type = xev.type;
05695 xev.any.send_event = ev.fSendEvent;
05696 if (ev.fType == kDestroyNotify) {
05697 xev.any.window = (GdkWindow *) ev.fWindow;
05698 }
05699 if (ev.fType == kFocusIn) {
05700 xev.type = GDK_FOCUS_CHANGE;
05701 xev.focus_change.type = xev.type;
05702 xev.focus_change.window = (GdkWindow *) ev.fWindow;
05703 xev.focus_change.in = TRUE;
05704 }
05705 if (ev.fType == kFocusOut) {
05706 xev.type = GDK_FOCUS_CHANGE;
05707 xev.focus_change.type = xev.type;
05708 xev.focus_change.window = (GdkWindow *) ev.fWindow;
05709 xev.focus_change.in = FALSE;
05710 }
05711 if (ev.fType == kGKeyPress || ev.fType == kKeyRelease) {
05712 xev.key.window = (GdkWindow *) ev.fWindow;
05713 xev.key.type = xev.type;
05714 MapModifierState(ev.fState, xev.key.state, kTRUE);
05715 xev.key.keyval = ev.fCode;
05716 }
05717 if (ev.fType == kButtonPress || ev.fType == kButtonRelease) {
05718 xev.button.window = (GdkWindow *) ev.fWindow;
05719 xev.button.type = xev.type;
05720 xev.button.x = ev.fX;
05721 xev.button.y = ev.fY;
05722 xev.button.x_root = ev.fXRoot;
05723 xev.button.y_root = ev.fYRoot;
05724 MapModifierState(ev.fState, xev.button.state, kTRUE);
05725 xev.button.button = ev.fCode;
05726 }
05727 if (ev.fType == kSelectionNotify) {
05728 xev.selection.window = (GdkWindow *) ev.fUser[0];
05729 xev.selection.requestor = (guint32) ev.fUser[0];
05730 xev.selection.selection = (GdkAtom) ev.fUser[1];
05731 xev.selection.target = (GdkAtom) ev.fUser[2];
05732 xev.selection.property = (GdkAtom) ev.fUser[3];
05733 xev.selection.type = xev.type;
05734 }
05735 if (ev.fType == kClientMessage) {
05736 if ((ev.fFormat == 32) && (ev.fHandle == gWM_DELETE_WINDOW)) {
05737 xev.type = GDK_DELETE;
05738 xev.any.type = xev.type;
05739 xev.any.window = (GdkWindow *) ev.fWindow;
05740 } else {
05741 xev.client.window = (GdkWindow *) ev.fWindow;
05742 xev.client.type = xev.type;
05743 xev.client.message_type = (GdkAtom) ev.fHandle;
05744 xev.client.data_format = ev.fFormat;
05745 xev.client.data.l[0] = ev.fUser[0];
05746 if (sizeof(ev.fUser[0]) > 4) {
05747 SplitLong(ev.fUser[1], xev.client.data.l[1],
05748 xev.client.data.l[3]);
05749 SplitLong(ev.fUser[2], xev.client.data.l[2],
05750 xev.client.data.l[4]);
05751 } else {
05752 xev.client.data.l[1] = ev.fUser[1];
05753 xev.client.data.l[2] = ev.fUser[2];
05754 xev.client.data.l[3] = ev.fUser[3];
05755 xev.client.data.l[4] = ev.fUser[4];
05756 }
05757 }
05758 }
05759 if (ev.fType == kMotionNotify) {
05760 xev.motion.window = (GdkWindow *) ev.fWindow;
05761 xev.motion.type = xev.type;
05762 xev.motion.x = ev.fX;
05763 xev.motion.y = ev.fY;
05764 xev.motion.x_root = ev.fXRoot;
05765 xev.motion.y_root = ev.fYRoot;
05766 }
05767 if ((ev.fType == kEnterNotify) || (ev.fType == kLeaveNotify)) {
05768 xev.crossing.window = (GdkWindow *) ev.fWindow;
05769 xev.crossing.type = xev.type;
05770 xev.crossing.x = ev.fX;
05771 xev.crossing.y = ev.fY;
05772 xev.crossing.x_root = ev.fXRoot;
05773 xev.crossing.y_root = ev.fYRoot;
05774 xev.crossing.mode = (GdkCrossingMode) ev.fCode;
05775 MapModifierState(ev.fState, xev.crossing.state, kTRUE);
05776 }
05777 if (ev.fType == kExpose) {
05778 xev.expose.window = (GdkWindow *) ev.fWindow;
05779 xev.expose.type = xev.type;
05780 xev.expose.area.x = ev.fX;
05781 xev.expose.area.y = ev.fY;
05782 xev.expose.area.width = ev.fWidth;
05783 xev.expose.area.height = ev.fHeight;
05784 xev.expose.count = ev.fCount;
05785 }
05786 if (ev.fType == kConfigureNotify) {
05787 xev.configure.window = (GdkWindow *) ev.fWindow;
05788 xev.configure.type = xev.type;
05789 xev.configure.x = ev.fX;
05790 xev.configure.y = ev.fY;
05791 xev.configure.width = ev.fWidth;
05792 xev.configure.height = ev.fHeight;
05793 }
05794 if (ev.fType == kSelectionClear) {
05795 xev.selection.window = (GdkWindow *) ev.fWindow;
05796 xev.selection.type = xev.type;
05797 xev.selection.selection = ev.fUser[0];
05798 }
05799 if (ev.fType == kSelectionRequest) {
05800 xev.selection.window = (GdkWindow *) ev.fUser[0];
05801 xev.selection.type = xev.type;
05802 xev.selection.selection = ev.fUser[1];
05803 xev.selection.target = ev.fUser[2];
05804 xev.selection.property = ev.fUser[3];
05805 }
05806 if ((ev.fType == kMapNotify) || (ev.fType == kUnmapNotify)) {
05807 xev.any.window = (GdkWindow *) ev.fWindow;
05808 }
05809 if (xev.type != GDK_CLIENT_EVENT)
05810 _set_event_time(xev, ev.fTime);
05811 } else {
05812
05813 ev.fType = kOtherEvent;
05814 if (xev.type == GDK_KEY_PRESS)
05815 ev.fType = kGKeyPress;
05816 if (xev.type == GDK_KEY_RELEASE)
05817 ev.fType = kKeyRelease;
05818 if (xev.type == GDK_BUTTON_PRESS)
05819 ev.fType = kButtonPress;
05820 if (xev.type == GDK_BUTTON_RELEASE)
05821 ev.fType = kButtonRelease;
05822 if (xev.type == GDK_MOTION_NOTIFY)
05823 ev.fType = kMotionNotify;
05824 if (xev.type == GDK_ENTER_NOTIFY)
05825 ev.fType = kEnterNotify;
05826 if (xev.type == GDK_LEAVE_NOTIFY)
05827 ev.fType = kLeaveNotify;
05828 if (xev.type == GDK_EXPOSE)
05829 ev.fType = kExpose;
05830 if (xev.type == GDK_CONFIGURE)
05831 ev.fType = kConfigureNotify;
05832 if (xev.type == GDK_MAP)
05833 ev.fType = kMapNotify;
05834 if (xev.type == GDK_UNMAP)
05835 ev.fType = kUnmapNotify;
05836 if (xev.type == GDK_DESTROY)
05837 ev.fType = kDestroyNotify;
05838 if (xev.type == GDK_SELECTION_CLEAR)
05839 ev.fType = kSelectionClear;
05840 if (xev.type == GDK_SELECTION_REQUEST)
05841 ev.fType = kSelectionRequest;
05842 if (xev.type == GDK_SELECTION_NOTIFY)
05843 ev.fType = kSelectionNotify;
05844
05845 ev.fSendEvent = kFALSE;
05846 ev.fTime = gdk_event_get_time((GdkEvent *)&xev);
05847 ev.fWindow = (Window_t) xev.any.window;
05848
05849 if ((xev.type == GDK_MAP) || (xev.type == GDK_UNMAP)) {
05850 ev.fWindow = (Window_t) xev.any.window;
05851 }
05852 if (xev.type == GDK_DELETE) {
05853 ev.fWindow = (Window_t) xev.any.window;
05854 ev.fType = kClientMessage;
05855 ev.fFormat = 32;
05856 ev.fHandle = gWM_DELETE_WINDOW;
05857 ev.fUser[0] = (Long_t) gWM_DELETE_WINDOW;
05858 if (sizeof(ev.fUser[0]) > 4) {
05859 AsmLong(xev.client.data.l[1], xev.client.data.l[3],
05860 ev.fUser[1]);
05861 AsmLong(xev.client.data.l[2], xev.client.data.l[4],
05862 ev.fUser[2]);
05863 } else {
05864 ev.fUser[1] = 0;
05865 ev.fUser[2] = 0;
05866 ev.fUser[3] = 0;
05867 ev.fUser[4] = 0;
05868 }
05869 }
05870 if (xev.type == GDK_DESTROY) {
05871 ev.fType = kDestroyNotify;
05872 ev.fHandle = (Window_t) xev.any.window;
05873 ev.fWindow = (Window_t) xev.any.window;
05874 }
05875 if (xev.type == GDK_FOCUS_CHANGE) {
05876 ev.fWindow = (Window_t) xev.focus_change.window;
05877 ev.fCode = kNotifyNormal;
05878 ev.fState = 0;
05879 if (xev.focus_change.in == TRUE) {
05880 ev.fType = kFocusIn;
05881 } else {
05882 ev.fType = kFocusOut;
05883 }
05884 }
05885 if (ev.fType == kGKeyPress || ev.fType == kKeyRelease) {
05886 ev.fWindow = (Window_t) xev.key.window;
05887 MapModifierState(ev.fState, xev.key.state, kFALSE);
05888 ev.fCode = xev.key.keyval;
05889 ev.fUser[1] = xev.key.length;
05890 if (xev.key.length > 0) ev.fUser[2] = xev.key.string[0];
05891 if (xev.key.length > 1) ev.fUser[3] = xev.key.string[1];
05892 if (xev.key.length > 2) ev.fUser[4] = xev.key.string[2];
05893 HWND tmpwin = (HWND) GetWindow((HWND) GDK_DRAWABLE_XID((GdkWindow *)xev.key.window), GW_CHILD);
05894 if (tmpwin) {
05895 ev.fUser[0] = (ULong_t) gdk_xid_table_lookup((HANDLE)tmpwin);
05896 } else {
05897 ev.fUser[0] = (ULong_t) xev.key.window;
05898 }
05899 }
05900 if (ev.fType == kButtonPress || ev.fType == kButtonRelease) {
05901 ev.fWindow = (Window_t) xev.button.window;
05902 ev.fX = xev.button.x;
05903 ev.fY = xev.button.y;
05904 ev.fXRoot = xev.button.x_root;
05905 ev.fYRoot = xev.button.y_root;
05906 MapModifierState(ev.fState, xev.button.state, kFALSE);
05907 ev.fCode = xev.button.button;
05908 POINT tpoint;
05909 tpoint.x = xev.button.x;
05910 tpoint.y = xev.button.y;
05911 HWND tmpwin = ChildWindowFromPoint((HWND) GDK_DRAWABLE_XID((GdkWindow *)xev.button.window), tpoint);
05912 if (tmpwin) {
05913 ev.fUser[0] = (ULong_t) gdk_xid_table_lookup((HANDLE)tmpwin);
05914 } else {
05915 ev.fUser[0] = (ULong_t) 0;
05916 }
05917 }
05918 if (ev.fType == kMotionNotify) {
05919 ev.fWindow = (Window_t) xev.motion.window;
05920 ev.fX = xev.motion.x;
05921 ev.fY = xev.motion.y;
05922 ev.fXRoot = xev.motion.x_root;
05923 ev.fYRoot = xev.motion.y_root;
05924 MapModifierState(ev.fState, xev.motion.state, kFALSE);
05925
05926 POINT tpoint;
05927 tpoint.x = xev.button.x;
05928 tpoint.y = xev.button.y;
05929 HWND tmpwin = ChildWindowFromPoint((HWND) GDK_DRAWABLE_XID((GdkWindow *)xev.motion.window), tpoint);
05930 if (tmpwin) {
05931 ev.fUser[0] = (ULong_t)gdk_xid_table_lookup((HANDLE)tmpwin);
05932 } else {
05933 ev.fUser[0] = (ULong_t) xev.motion.window;
05934 }
05935 }
05936 if (ev.fType == kEnterNotify || ev.fType == kLeaveNotify) {
05937 ev.fWindow = (Window_t) xev.crossing.window;
05938 ev.fX = xev.crossing.x;
05939 ev.fY = xev.crossing.y;
05940 ev.fXRoot = xev.crossing.x_root;
05941 ev.fYRoot = xev.crossing.y_root;
05942 ev.fCode = xev.crossing.mode;
05943 MapModifierState(ev.fState, xev.crossing.state, kFALSE);
05944 }
05945 if (ev.fType == kExpose) {
05946 ev.fWindow = (Window_t) xev.expose.window;
05947 ev.fX = xev.expose.area.x;
05948 ev.fY = xev.expose.area.y;
05949 ev.fWidth = xev.expose.area.width;
05950 ev.fHeight = xev.expose.area.height;
05951 ev.fCount = xev.expose.count;
05952 }
05953 if (ev.fType == kConfigureNotify) {
05954 ev.fWindow = (Window_t) xev.configure.window;
05955 ev.fX = xev.configure.x;
05956 ev.fY = xev.configure.y;
05957 ev.fWidth = xev.configure.width;
05958 ev.fHeight = xev.configure.height;
05959 }
05960 if (xev.type == GDK_CLIENT_EVENT) {
05961 ev.fWindow = (Window_t) xev.client.window;
05962 ev.fType = kClientMessage;
05963 ev.fHandle = xev.client.message_type;
05964 ev.fFormat = xev.client.data_format;
05965 ev.fUser[0] = xev.client.data.l[0];
05966 if (sizeof(ev.fUser[0]) > 4) {
05967 AsmLong(xev.client.data.l[1], xev.client.data.l[3],
05968 ev.fUser[1]);
05969 AsmLong(xev.client.data.l[2], xev.client.data.l[4],
05970 ev.fUser[2]);
05971 } else {
05972 ev.fUser[1] = xev.client.data.l[1];
05973 ev.fUser[2] = xev.client.data.l[2];
05974 ev.fUser[3] = xev.client.data.l[3];
05975 ev.fUser[4] = xev.client.data.l[4];
05976 }
05977 }
05978 if (ev.fType == kSelectionClear) {
05979 ev.fWindow = (Window_t) xev.selection.window;
05980 ev.fUser[0] = xev.selection.selection;
05981 }
05982 if (ev.fType == kSelectionRequest) {
05983 ev.fWindow = (Window_t) xev.selection.window;
05984 ev.fUser[0] = (ULong_t) xev.selection.window;
05985 ev.fUser[1] = xev.selection.selection;
05986 ev.fUser[2] = xev.selection.target;
05987 ev.fUser[3] = xev.selection.property;
05988 }
05989 if (ev.fType == kSelectionNotify) {
05990 ev.fWindow = (Window_t) xev.selection.window;
05991 ev.fUser[0] = (ULong_t) xev.selection.window;
05992 ev.fUser[1] = xev.selection.selection;
05993 ev.fUser[2] = xev.selection.target;
05994 ev.fUser[3] = xev.selection.property;
05995 }
05996 if (xev.type == GDK_SCROLL) {
05997 ev.fType = kButtonRelease;
05998 if (xev.scroll.direction == GDK_SCROLL_UP) {
05999 ev.fCode = kButton4;
06000 } else if (xev.scroll.direction == GDK_SCROLL_DOWN) {
06001 ev.fCode = kButton5;
06002 }
06003 ev.fWindow = (Window_t) xev.scroll.window;
06004 ev.fX = xev.scroll.x;
06005 ev.fY = xev.scroll.y;
06006 ev.fXRoot = xev.scroll.x_root;
06007 ev.fYRoot = xev.scroll.y_root;
06008 POINT tpoint;
06009 tpoint.x = xev.scroll.x;
06010 tpoint.y = xev.scroll.y;
06011 HWND tmpwin = ChildWindowFromPoint((HWND) GDK_DRAWABLE_XID((GdkWindow *)xev.scroll.window), tpoint);
06012 if (tmpwin) {
06013 ev.fUser[0] = (ULong_t)gdk_xid_table_lookup((HANDLE)tmpwin);
06014 } else {
06015 ev.fUser[0] = (ULong_t) 0;
06016 }
06017 }
06018 }
06019 }
06020
06021
06022 void TGWin32::Bell(Int_t percent)
06023 {
06024
06025
06026 gSystem->Beep();
06027 }
06028
06029
06030 void TGWin32::CopyArea(Drawable_t src, Drawable_t dest, GContext_t gc,
06031 Int_t src_x, Int_t src_y, UInt_t width,
06032 UInt_t height, Int_t dest_x, Int_t dest_y)
06033 {
06034
06035
06036
06037
06038 if (!src || !dest) return;
06039
06040 gdk_window_copy_area((GdkDrawable *) dest, (GdkGC *) gc, dest_x, dest_y,
06041 (GdkDrawable *) src, src_x, src_y, width, height);
06042 }
06043
06044
06045 void TGWin32::ChangeWindowAttributes(Window_t id, SetWindowAttributes_t * attr)
06046 {
06047
06048
06049 if (!id) return;
06050
06051 GdkWMDecoration deco;
06052 GdkColor color;
06053 GdkEventMask xevent_mask;
06054 UInt_t xevmask;
06055 Mask_t evmask;
06056 HWND w, flag;
06057
06058 if (attr && (attr->fMask & kWAEventMask)) {
06059 evmask = (Mask_t) attr->fEventMask;
06060 MapEventMask(evmask, xevmask);
06061 gdk_window_set_events((GdkWindow *) id, (GdkEventMask) xevmask);
06062 }
06063 if (attr && (attr->fMask & kWABackPixel)) {
06064 color.pixel = attr->fBackgroundPixel;
06065 color.red = GetRValue(attr->fBackgroundPixel);
06066 color.green = GetGValue(attr->fBackgroundPixel);
06067 color.blue = GetBValue(attr->fBackgroundPixel);
06068 gdk_window_set_background((GdkWindow *) id, &color);
06069 }
06070
06071
06072 if (attr && (attr->fMask & kWABackPixmap)) {
06073 gdk_window_set_back_pixmap((GdkWindow *) id,
06074 (GdkPixmap *) attr->fBackgroundPixmap, 0);
06075 }
06076 if (attr && (attr->fMask & kWACursor)) {
06077 gdk_window_set_cursor((GdkWindow *) id, (GdkCursor *) attr->fCursor);
06078 }
06079 if (attr && (attr->fMask & kWAColormap)) {
06080 gdk_window_set_colormap((GdkWindow *) id,(GdkColormap *) attr->fColormap);
06081 }
06082 if (attr && (attr->fMask & kWABorderWidth)) {
06083 if (attr->fBorderWidth > 0) {
06084 gdk_window_set_decorations((GdkWindow *) id,
06085 (GdkWMDecoration) GDK_DECOR_BORDER);
06086 }
06087 }
06088 }
06089
06090
06091 void TGWin32::ChangeProperty(Window_t id, Atom_t property, Atom_t type,
06092 UChar_t * data, Int_t len)
06093 {
06094
06095
06096
06097
06098 if (!id) return;
06099
06100 gdk_property_change((GdkWindow *) id, (GdkAtom) property,
06101 (GdkAtom) type, 8, GDK_PROP_MODE_REPLACE, data,len);
06102 }
06103
06104
06105 void TGWin32::DrawLine(Drawable_t id, GContext_t gc, Int_t x1, Int_t y1,
06106 Int_t x2, Int_t y2)
06107 {
06108
06109
06110 if (!id) return;
06111
06112 gdk_draw_line((GdkDrawable *) id, (GdkGC *) gc, x1, y1, x2, y2);
06113 }
06114
06115
06116 void TGWin32::ClearArea(Window_t id, Int_t x, Int_t y, UInt_t w, UInt_t h)
06117 {
06118
06119
06120 if (!id) return;
06121
06122 gdk_window_clear_area((GdkWindow *) id, x, y, w, h);
06123 }
06124
06125
06126 void TGWin32::WMDeleteNotify(Window_t id)
06127 {
06128
06129
06130 if (!id) return;
06131
06132 Atom prop;
06133 prop = (Atom_t) gdk_atom_intern("WM_DELETE_WINDOW", FALSE);
06134
06135 W32ChangeProperty((HWND) GDK_DRAWABLE_XID((GdkWindow *) id),
06136 prop, XA_ATOM, 32, GDK_PROP_MODE_REPLACE,
06137 (unsigned char *) &gWM_DELETE_WINDOW, 1);
06138 }
06139
06140
06141 void TGWin32::SetKeyAutoRepeat(Bool_t on)
06142 {
06143
06144
06145 if (on) {
06146 gdk_key_repeat_restore();
06147 } else {
06148 gdk_key_repeat_disable();
06149 }
06150 }
06151
06152
06153 void TGWin32::GrabKey(Window_t id, Int_t keycode, UInt_t modifier, Bool_t grab)
06154 {
06155
06156
06157
06158
06159
06160 UInt_t xmod;
06161
06162 MapModifierState(modifier, xmod);
06163
06164 if (grab) {
06165 gdk_key_grab(keycode, (GdkEventMask)xmod, (GdkWindow *)id);
06166 } else {
06167 gdk_key_ungrab(keycode, (GdkEventMask)xmod, (GdkWindow *)id);
06168 }
06169 }
06170
06171
06172 void TGWin32::GrabButton(Window_t id, EMouseButton button, UInt_t modifier,
06173 UInt_t evmask, Window_t confine, Cursor_t cursor,
06174 Bool_t grab)
06175 {
06176
06177
06178
06179
06180
06181 UInt_t xevmask;
06182 UInt_t xmod;
06183
06184 if (!id) return;
06185
06186 MapModifierState(modifier, xmod);
06187
06188 if (grab) {
06189 MapEventMask(evmask, xevmask);
06190 gdk_button_grab(button, xmod, ( GdkWindow *)id, 1, (GdkEventMask)xevmask,
06191 (GdkWindow*)confine, (GdkCursor*)cursor);
06192 } else {
06193 gdk_button_ungrab(button, xmod, ( GdkWindow *)id);
06194 }
06195 }
06196
06197
06198 void TGWin32::GrabPointer(Window_t id, UInt_t evmask, Window_t confine,
06199 Cursor_t cursor, Bool_t grab, Bool_t owner_events)
06200 {
06201
06202
06203
06204
06205 UInt_t xevmask;
06206 MapEventMask(evmask, xevmask);
06207
06208 if (grab) {
06209 if(!::IsWindowVisible((HWND)GDK_DRAWABLE_XID(id))) return;
06210 gdk_pointer_grab((GdkWindow *) id, owner_events, (GdkEventMask) xevmask,
06211 (GdkWindow *) confine, (GdkCursor *) cursor,
06212 GDK_CURRENT_TIME);
06213 } else {
06214 gdk_pointer_ungrab(GDK_CURRENT_TIME);
06215 ::SetCursor((HCURSOR)GDK_CURSOR_XID(fCursors[kPointer]));
06216 }
06217 }
06218
06219
06220 void TGWin32::SetWindowName(Window_t id, char *name)
06221 {
06222
06223
06224 if (!id) return;
06225
06226 gdk_window_set_title((GdkWindow *) id, name);
06227 }
06228
06229
06230 void TGWin32::SetIconName(Window_t id, char *name)
06231 {
06232
06233
06234 if (!id) return;
06235
06236 gdk_window_set_icon_name((GdkWindow *) id, name);
06237 }
06238
06239
06240 void TGWin32::SetIconPixmap(Window_t id, Pixmap_t pic)
06241 {
06242
06243
06244 if (!id) return;
06245
06246 gdk_window_set_icon((GdkWindow *)id, NULL, (GdkPixmap *)pic, (GdkPixmap *)pic);
06247 }
06248
06249 #define safestrlen(s) ((s) ? strlen(s) : 0)
06250
06251
06252 void TGWin32::SetClassHints(Window_t id, char *className, char *resourceName)
06253 {
06254
06255
06256 if (!id) return;
06257
06258 char *class_string;
06259 char *s;
06260 int len_nm, len_cl;
06261 GdkAtom type, prop;
06262
06263 prop = gdk_atom_intern("WM_CLASS", kFALSE);
06264
06265 len_nm = safestrlen(resourceName);
06266 len_cl = safestrlen(className);
06267
06268 if ((class_string = s =
06269 (char *) malloc((unsigned) (len_nm + len_cl + 2)))) {
06270 if (len_nm) {
06271 strcpy(s, resourceName);
06272 s += len_nm + 1;
06273 } else
06274 *s++ = '\0';
06275 if (len_cl) {
06276 strcpy(s, className);
06277 } else {
06278 *s = '\0';
06279 }
06280
06281 W32ChangeProperty((HWND) GDK_DRAWABLE_XID((GdkWindow *) id),
06282 (Atom) XA_WM_CLASS, (Atom) XA_WM_CLASS, 8,
06283 GDK_PROP_MODE_REPLACE,
06284 (unsigned char *) class_string,
06285 len_nm + len_cl + 2);
06286 free(class_string);
06287 }
06288 }
06289
06290
06291 void TGWin32::SetMWMHints(Window_t id, UInt_t value, UInt_t funcs,
06292 UInt_t input)
06293 {
06294
06295
06296 if (!id) return;
06297
06298 gdk_window_set_decorations((GdkDrawable *) id, (GdkWMDecoration) value);
06299 gdk_window_set_functions((GdkDrawable *) id, (GdkWMFunction) funcs);
06300 }
06301
06302
06303 void TGWin32::SetWMPosition(Window_t id, Int_t x, Int_t y)
06304 {
06305
06306
06307 if (!id) return;
06308
06309 gdk_window_move((GdkDrawable *) id, x, y);
06310 }
06311
06312
06313 void TGWin32::SetWMSize(Window_t id, UInt_t w, UInt_t h)
06314 {
06315
06316
06317 if (!id) return;
06318
06319 gdk_window_resize((GdkWindow *) id, w, h);
06320 }
06321
06322
06323 void TGWin32::SetWMSizeHints(Window_t id, UInt_t wmin, UInt_t hmin,
06324 UInt_t wmax, UInt_t hmax,
06325 UInt_t winc, UInt_t hinc)
06326 {
06327
06328
06329
06330 if (!id) return;
06331
06332 GdkGeometry hints;
06333 GdkWindowHints flags;
06334
06335 flags = (GdkWindowHints) (GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE |
06336 GDK_HINT_RESIZE_INC);
06337 hints.min_width = (Int_t) wmin;
06338 hints.max_width = (Int_t) wmax;
06339 hints.min_height = (Int_t) hmin;
06340 hints.max_height = (Int_t) hmax;
06341 hints.width_inc = (Int_t) winc;
06342 hints.height_inc = (Int_t) hinc;
06343
06344 gdk_window_set_geometry_hints((GdkWindow *) id, (GdkGeometry *) &hints,
06345 (GdkWindowHints) flags);
06346 }
06347
06348
06349 void TGWin32::SetWMState(Window_t id, EInitialState state)
06350 {
06351
06352
06353 if (!id) return;
06354
06355 #if 0
06356 XWMHints hints;
06357 Int_t xstate = NormalState;
06358
06359 if (state == kNormalState)
06360 xstate = NormalState;
06361 if (state == kIconicState)
06362 xstate = IconicState;
06363
06364 hints.flags = StateHint;
06365 hints.initial_state = xstate;
06366
06367 XSetWMHints((GdkWindow *) id, &hints);
06368 #endif
06369 }
06370
06371
06372 void TGWin32::SetWMTransientHint(Window_t id, Window_t main_id)
06373 {
06374
06375
06376 if (!id) return;
06377
06378 gdk_window_set_transient_for((GdkWindow *) id, (GdkWindow *) main_id);
06379 }
06380
06381
06382 void TGWin32::DrawString(Drawable_t id, GContext_t gc, Int_t x, Int_t y,
06383 const char *s, Int_t len)
06384 {
06385
06386
06387 if (!id) return;
06388
06389 GdkGCValues values;
06390 gdk_gc_get_values((GdkGC *) gc, &values);
06391 gdk_win32_draw_text((GdkDrawable *) id, (GdkFont *) values.font,
06392 (GdkGC *) gc, x, y, (const gchar *)s, len);
06393 }
06394
06395
06396 Int_t TGWin32::TextWidth(FontStruct_t font, const char *s, Int_t len)
06397 {
06398
06399
06400 return gdk_text_width((GdkFont *)font, s, len);
06401 }
06402
06403
06404 void TGWin32::GetFontProperties(FontStruct_t font, Int_t & max_ascent,
06405 Int_t & max_descent)
06406 {
06407
06408
06409 GdkFont *f = (GdkFont *) font;
06410 max_ascent = f->ascent;
06411 max_descent = f->descent;
06412 }
06413
06414
06415 void TGWin32::GetGCValues(GContext_t gc, GCValues_t & gval)
06416 {
06417
06418
06419
06420 GdkGCValues xgval;
06421 ULong_t xmask;
06422
06423 MapGCValues(gval, xmask, xgval, kTRUE);
06424 gdk_gc_get_values((GdkGC *) gc, &xgval);
06425 MapGCValues(gval, xmask, xgval, kFALSE);
06426 }
06427
06428
06429 FontStruct_t TGWin32::GetFontStruct(FontH_t fh)
06430 {
06431
06432
06433
06434 return (FontStruct_t) gdk_font_ref((GdkFont *) fh);
06435 }
06436
06437
06438 void TGWin32::FreeFontStruct(FontStruct_t fs)
06439 {
06440
06441
06442 gdk_font_unref((GdkFont *) fs);
06443 }
06444
06445
06446 void TGWin32::ClearWindow(Window_t id)
06447 {
06448
06449
06450 if (!id) return;
06451
06452 gdk_window_clear((GdkDrawable *) id);
06453 }
06454
06455
06456 Int_t TGWin32::KeysymToKeycode(UInt_t keysym)
06457 {
06458
06459
06460
06461
06462 UInt_t xkeysym;
06463 MapKeySym(keysym, xkeysym);
06464 return xkeysym;
06465 }
06466
06467
06468 void TGWin32::FillRectangle(Drawable_t id, GContext_t gc, Int_t x, Int_t y,
06469 UInt_t w, UInt_t h)
06470 {
06471
06472
06473 if (!id) return;
06474
06475 gdk_win32_draw_rectangle((GdkDrawable *) id, (GdkGC *) gc, kTRUE, x, y, w, h);
06476 }
06477
06478
06479 void TGWin32::DrawRectangle(Drawable_t id, GContext_t gc, Int_t x, Int_t y,
06480 UInt_t w, UInt_t h)
06481 {
06482
06483
06484 if (!id) return;
06485
06486 gdk_win32_draw_rectangle((GdkDrawable *) id, (GdkGC *) gc, kFALSE, x, y, w, h);
06487 }
06488
06489
06490 void TGWin32::DrawSegments(Drawable_t id, GContext_t gc, Segment_t * seg,
06491 Int_t nseg)
06492 {
06493
06494
06495 if (!id) return;
06496
06497 gdk_win32_draw_segments((GdkDrawable *) id, (GdkGC *) gc, (GdkSegment *)seg, nseg);
06498 }
06499
06500
06501 void TGWin32::SelectInput(Window_t id, UInt_t evmask)
06502 {
06503
06504
06505
06506
06507
06508 if (!id) return;
06509
06510 UInt_t xevmask;
06511 MapEventMask(evmask, xevmask, kTRUE);
06512 gdk_window_set_events((GdkWindow *) id, (GdkEventMask)xevmask);
06513 }
06514
06515
06516 Window_t TGWin32::GetInputFocus()
06517 {
06518
06519
06520 HWND hwnd = ::GetFocus();
06521 return (Window_t) gdk_xid_table_lookup(hwnd);
06522 }
06523
06524
06525 void TGWin32::SetInputFocus(Window_t id)
06526 {
06527
06528
06529 if (!id) return;
06530
06531 HWND hwnd = (HWND)GDK_DRAWABLE_XID((GdkWindow *)id);
06532 ::SetFocus(hwnd);
06533 }
06534
06535
06536 Window_t TGWin32::GetPrimarySelectionOwner()
06537 {
06538
06539
06540
06541 return (Window_t)gdk_selection_owner_get(gClipboardAtom);
06542 }
06543
06544
06545 void TGWin32::SetPrimarySelectionOwner(Window_t id)
06546 {
06547
06548
06549
06550 if (!id) return;
06551
06552 gdk_selection_owner_set((GdkWindow *) id, gClipboardAtom, GDK_CURRENT_TIME, 0);
06553 }
06554
06555
06556 void TGWin32::ConvertPrimarySelection(Window_t id, Atom_t clipboard, Time_t when)
06557 {
06558
06559
06560
06561
06562
06563
06564
06565
06566
06567
06568 if (!id) return;
06569
06570 gdk_selection_convert((GdkWindow *) id, clipboard,
06571 gdk_atom_intern("GDK_TARGET_STRING", 0), when);
06572 }
06573
06574
06575 void TGWin32::LookupString(Event_t * event, char *buf, Int_t buflen,
06576 UInt_t & keysym)
06577 {
06578
06579
06580
06581
06582
06583 KeySym xkeysym;
06584 _lookup_string(event, buf, buflen);
06585 UInt_t ks, xks = (UInt_t) event->fCode;
06586 MapKeySym(ks, xks, kFALSE);
06587 keysym = (Int_t) ks;
06588 }
06589
06590
06591 void TGWin32::MapKeySym(UInt_t & keysym, UInt_t & xkeysym, Bool_t tox)
06592 {
06593
06594
06595
06596 if (tox) {
06597 xkeysym = GDK_VoidSymbol;
06598 if (keysym < 127) {
06599 xkeysym = keysym;
06600 } else if (keysym >= kKey_F1 && keysym <= kKey_F35) {
06601 xkeysym = GDK_F1 + (keysym - (UInt_t) kKey_F1);
06602 } else {
06603 for (int i = 0; gKeyMap[i].fKeySym; i++) {
06604 if (keysym == (UInt_t) gKeyMap[i].fKeySym) {
06605 xkeysym = (UInt_t) gKeyMap[i].fXKeySym;
06606 break;
06607 }
06608 }
06609 }
06610 } else {
06611 keysym = kKey_Unknown;
06612
06613 if (xkeysym < 127) {
06614 keysym = xkeysym;
06615 } else if (xkeysym >= GDK_F1 && xkeysym <= GDK_F35) {
06616 keysym = kKey_F1 + (xkeysym - GDK_F1);
06617 } else if (xkeysym >= GDK_KP_0 && xkeysym <= GDK_KP_9) {
06618 keysym = kKey_0 + (xkeysym - GDK_KP_0);
06619 } else {
06620 for (int i = 0; gKeyMap[i].fXKeySym; i++) {
06621 if (xkeysym == gKeyMap[i].fXKeySym) {
06622 keysym = (UInt_t) gKeyMap[i].fKeySym;
06623 break;
06624 }
06625 }
06626 }
06627 }
06628 }
06629
06630
06631 void TGWin32::GetPasteBuffer(Window_t id, Atom_t atom, TString & text,
06632 Int_t & nchar, Bool_t del)
06633 {
06634
06635
06636
06637 if (!id) return;
06638
06639 char *data;
06640 int nread, actual_format;
06641
06642 nread = gdk_selection_property_get((GdkWindow *) id,
06643 (unsigned char **) &data,
06644 (GdkAtom *) & atom, &actual_format);
06645
06646 if ((nread == 0) || (data == NULL)) {
06647 nchar = 0;
06648 return;
06649 }
06650
06651 text.Insert(0, (const char *) data);
06652 nchar = 1;
06653 g_free(data);
06654
06655
06656 gdk_property_delete((GdkWindow *) id,
06657 gdk_atom_intern("GDK_SELECTION", FALSE));
06658 }
06659
06660
06661 void TGWin32::TranslateCoordinates(Window_t src, Window_t dest,
06662 Int_t src_x, Int_t src_y,
06663 Int_t &dest_x, Int_t &dest_y,
06664 Window_t &child)
06665 {
06666
06667
06668
06669
06670
06671 if (!src || !dest) return;
06672
06673 HWND sw, dw, ch = NULL;
06674 POINT point;
06675 sw = (HWND)GDK_DRAWABLE_XID((GdkWindow *)src);
06676 dw = (HWND)GDK_DRAWABLE_XID((GdkWindow *)dest);
06677 point.x = src_x;
06678 point.y = src_y;
06679 ::MapWindowPoints(sw,
06680 dw,
06681 &point,
06682 1);
06683 ch = ::ChildWindowFromPointEx(dw, point, CWP_SKIPDISABLED | CWP_SKIPINVISIBLE);
06684 child = (Window_t)gdk_xid_table_lookup(ch);
06685
06686 if (child == src) {
06687 child = (Window_t) 0;
06688 }
06689 dest_x = point.x;
06690 dest_y = point.y;
06691 }
06692
06693
06694 void TGWin32::GetWindowSize(Drawable_t id, Int_t & x, Int_t & y,
06695 UInt_t & w, UInt_t & h)
06696 {
06697
06698
06699
06700 if (!id) return;
06701
06702 Int_t ddum;
06703 if (GDK_DRAWABLE_TYPE(id) == GDK_DRAWABLE_PIXMAP) {
06704 x = y = 0;
06705 gdk_drawable_get_size((GdkDrawable *)id, (int*)&w, (int*)&h);
06706 }
06707 else {
06708 gdk_window_get_geometry((GdkDrawable *) id, &x, &y, (int*)&w,
06709 (int*)&h, &ddum);
06710 }
06711 }
06712
06713
06714 void TGWin32::FillPolygon(Window_t id, GContext_t gc, Point_t * points,
06715 Int_t npnt)
06716 {
06717
06718
06719
06720
06721
06722
06723
06724 if (!id) return;
06725
06726 gdk_win32_draw_polygon((GdkWindow *) id, (GdkGC *) gc, 1, (GdkPoint *) points, npnt);
06727 }
06728
06729
06730 void TGWin32::QueryPointer(Window_t id, Window_t &rootw,
06731 Window_t &childw, Int_t &root_x,
06732 Int_t &root_y, Int_t &win_x, Int_t &win_y,
06733 UInt_t &mask)
06734 {
06735
06736
06737
06738
06739
06740
06741
06742
06743 if (!id) return;
06744
06745 POINT mousePt, sPt, currPt;
06746 HWND chw, window;
06747 UInt_t umask = 0;
06748 BYTE kbd[256];
06749
06750 window = (HWND)GDK_DRAWABLE_XID((GdkWindow *)id);
06751 rootw = (Window_t)GDK_ROOT_PARENT();
06752 ::GetCursorPos(&currPt);
06753 chw = ::WindowFromPoint(currPt);
06754 childw = (Window_t)gdk_xid_table_lookup(chw);
06755 root_x = currPt.x;
06756 root_y = currPt.y;
06757
06758 ::ScreenToClient(window, &currPt);
06759 win_x = currPt.x;
06760 win_y = currPt.y;
06761
06762 ::GetKeyboardState (kbd);
06763
06764 if (kbd[VK_SHIFT] & 0x80) {
06765 umask |= GDK_SHIFT_MASK;
06766 }
06767 if (kbd[VK_CAPITAL] & 0x80) {
06768 umask |= GDK_LOCK_MASK;
06769 }
06770 if (kbd[VK_CONTROL] & 0x80) {
06771 umask |= GDK_CONTROL_MASK;
06772 }
06773 if (kbd[VK_MENU] & 0x80) {
06774 umask |= GDK_MOD1_MASK;
06775 }
06776 if (kbd[VK_LBUTTON] & 0x80) {
06777 umask |= GDK_BUTTON1_MASK;
06778 }
06779 if (kbd[VK_MBUTTON] & 0x80) {
06780 umask |= GDK_BUTTON2_MASK;
06781 }
06782 if (kbd[VK_RBUTTON] & 0x80) {
06783 umask |= GDK_BUTTON3_MASK;
06784 }
06785
06786 MapModifierState(mask, umask, kFALSE);
06787 }
06788
06789
06790 void TGWin32::SetForeground(GContext_t gc, ULong_t foreground)
06791 {
06792
06793
06794
06795 GdkColor fore;
06796 fore.pixel = foreground;
06797 fore.red = GetRValue(foreground);
06798 fore.green = GetGValue(foreground);
06799 fore.blue = GetBValue(foreground);
06800 gdk_gc_set_foreground((GdkGC *) gc, &fore);
06801 }
06802
06803
06804 void TGWin32::SetClipRectangles(GContext_t gc, Int_t x, Int_t y,
06805 Rectangle_t * recs, Int_t n)
06806 {
06807
06808
06809
06810
06811 Int_t i;
06812 GdkRectangle *grects = new GdkRectangle[n];
06813
06814 for (i = 0; i < n; i++) {
06815 grects[i].x = x+recs[i].fX;
06816 grects[i].y = y+recs[i].fY;
06817 grects[i].width = recs[i].fWidth;
06818 grects[i].height = recs[i].fHeight;
06819 }
06820
06821 for (i = 0; i < n; i++) {
06822 gdk_gc_set_clip_rectangle((GdkGC *)gc, (GdkRectangle*)recs);
06823 }
06824 delete [] grects;
06825 }
06826
06827
06828 void TGWin32::Update(Int_t mode)
06829 {
06830
06831
06832
06833
06834 GdiFlush();
06835 }
06836
06837
06838 Region_t TGWin32::CreateRegion()
06839 {
06840
06841
06842 return (Region_t) gdk_region_new();
06843 }
06844
06845
06846 void TGWin32::DestroyRegion(Region_t reg)
06847 {
06848
06849
06850 gdk_region_destroy((GdkRegion *) reg);
06851 }
06852
06853
06854 void TGWin32::UnionRectWithRegion(Rectangle_t * rect, Region_t src, Region_t dest)
06855 {
06856
06857
06858 GdkRectangle r;
06859 r.x = rect->fX;
06860 r.y = rect->fY;
06861 r.width = rect->fWidth;
06862 r.height = rect->fHeight;
06863 dest = (Region_t) gdk_region_union_with_rect((GdkRegion *) src, &r);
06864 }
06865
06866
06867 Region_t TGWin32::PolygonRegion(Point_t * points, Int_t np, Bool_t winding)
06868 {
06869
06870
06871
06872 return (Region_t) gdk_region_polygon((GdkPoint*)points, np,
06873 winding ? GDK_WINDING_RULE : GDK_EVEN_ODD_RULE);
06874 }
06875
06876
06877 void TGWin32::UnionRegion(Region_t rega, Region_t regb, Region_t result)
06878 {
06879
06880
06881
06882 result = (Region_t) gdk_regions_union((GdkRegion *) rega, (GdkRegion *) regb);
06883 }
06884
06885
06886 void TGWin32::IntersectRegion(Region_t rega, Region_t regb,
06887 Region_t result)
06888 {
06889
06890
06891
06892 result = (Region_t) gdk_regions_intersect((GdkRegion *) rega,(GdkRegion *) regb);
06893 }
06894
06895
06896 void TGWin32::SubtractRegion(Region_t rega, Region_t regb, Region_t result)
06897 {
06898
06899
06900 result = (Region_t)gdk_regions_subtract((GdkRegion *) rega,(GdkRegion *) regb);
06901 }
06902
06903
06904 void TGWin32::XorRegion(Region_t rega, Region_t regb, Region_t result)
06905 {
06906
06907
06908
06909 result = (Region_t) gdk_regions_xor((GdkRegion *) rega, (GdkRegion *) regb);
06910 }
06911
06912
06913 Bool_t TGWin32::EmptyRegion(Region_t reg)
06914 {
06915
06916
06917 return (Bool_t) gdk_region_empty((GdkRegion *) reg);
06918 }
06919
06920
06921 Bool_t TGWin32::PointInRegion(Int_t x, Int_t y, Region_t reg)
06922 {
06923
06924
06925 return (Bool_t) gdk_region_point_in((GdkRegion *) reg, x, y);
06926 }
06927
06928
06929 Bool_t TGWin32::EqualRegion(Region_t rega, Region_t regb)
06930 {
06931
06932
06933 return (Bool_t) gdk_region_equal((GdkRegion *) rega, (GdkRegion *) regb);
06934 }
06935
06936
06937 void TGWin32::GetRegionBox(Region_t reg, Rectangle_t * rect)
06938 {
06939
06940
06941 GdkRectangle r;
06942 gdk_region_get_clipbox((GdkRegion *) reg, &r);
06943 rect->fX = r.x;
06944 rect->fY = r.y;
06945 rect->fWidth = r.width;
06946 rect->fHeight = r.height;
06947 }
06948
06949
06950 char **TGWin32::ListFonts(const char *fontname, Int_t , Int_t &count)
06951 {
06952
06953
06954 char foundry[32], family[100], weight[32], slant[32], font_name[256];
06955 char **fontlist;
06956 Int_t n1, fontcount = 0;
06957
06958 sscanf(fontname, "-%30[^-]-%100[^-]-%30[^-]-%30[^-]-%n",
06959 foundry, family, weight, slant, &n1);
06960
06961 if(!stricmp(weight,"medium")) {
06962 sprintf(weight,"normal");
06963 }
06964
06965 sprintf(font_name, "-%s-%s-%s-%s-*", foundry, family, weight, slant);
06966 fontlist = gdk_font_list_new(font_name, &fontcount);
06967 count = fontcount;
06968
06969 if (fontcount > 0) return fontlist;
06970 return 0;
06971 }
06972
06973
06974 void TGWin32::FreeFontNames(char **fontlist)
06975 {
06976
06977
06978 gdk_font_list_free(fontlist);
06979 }
06980
06981
06982 Drawable_t TGWin32::CreateImage(UInt_t width, UInt_t height)
06983 {
06984
06985
06986 return (Drawable_t) gdk_image_new(GDK_IMAGE_SHARED, gdk_visual_get_best(),
06987 width, height);
06988 }
06989
06990
06991 void TGWin32::GetImageSize(Drawable_t id, UInt_t &width, UInt_t &height)
06992 {
06993
06994
06995 width = ((GdkImage*)id)->width;
06996 height = ((GdkImage*)id)->height;
06997 }
06998
06999
07000 void TGWin32::PutPixel(Drawable_t id, Int_t x, Int_t y, ULong_t pixel)
07001 {
07002
07003
07004 if (!id) return;
07005
07006 GdkImage *image = (GdkImage *)id;
07007 if (image->depth == 1) {
07008 if (pixel & 1) {
07009 ((UChar_t *) image->mem)[y * image->bpl + (x >> 3)] |= (1 << (7 - (x & 0x7)));
07010 } else {
07011 ((UChar_t *) image->mem)[y * image->bpl + (x >> 3)] &= ~(1 << (7 - (x & 0x7)));
07012 }
07013 } else {
07014 UChar_t *pixelp = (UChar_t *) image->mem + y * image->bpl + x * image->bpp;
07015
07016 switch (image->bpp) {
07017 case 4:
07018 pixelp[3] = 0;
07019 case 3:
07020 pixelp[2] = ((pixel >> 16) & 0xFF);
07021 case 2:
07022 pixelp[1] = ((pixel >> 8) & 0xFF);
07023 case 1:
07024 pixelp[0] = (pixel & 0xFF);
07025 }
07026 }
07027 }
07028
07029
07030 void TGWin32::PutImage(Drawable_t id, GContext_t gc, Drawable_t img, Int_t dx,
07031 Int_t dy, Int_t x, Int_t y, UInt_t w, UInt_t h)
07032 {
07033
07034
07035 if (!id) return;
07036
07037 gdk_draw_image((GdkDrawable *) id, (GdkGC *)gc, (GdkImage *)img,
07038 x, y, dx, dy, w, h);
07039 ::GdiFlush();
07040 }
07041
07042
07043 void TGWin32::DeleteImage(Drawable_t img)
07044 {
07045
07046
07047 gdk_image_unref((GdkImage *)img);
07048 }
07049
07050
07051 unsigned char *TGWin32::GetColorBits(Drawable_t wid, Int_t x, Int_t y,
07052 UInt_t width, UInt_t height)
07053 {
07054
07055
07056
07057
07058
07059
07060
07061
07062
07063 HDC hdc, memdc;
07064 BITMAPINFO bmi;
07065 HGDIOBJ oldbitmap1, oldbitmap2;
07066 BITMAP bm;
07067 HBITMAP ximage = 0;
07068 VOID *bmbits = 0;
07069 unsigned char *ret = 0;
07070
07071 if (GDK_DRAWABLE_TYPE(wid) == GDK_DRAWABLE_PIXMAP) {
07072 hdc = ::CreateCompatibleDC(NULL);
07073 oldbitmap1 = ::SelectObject(hdc, GDK_DRAWABLE_XID(wid));
07074 ::GetObject(GDK_DRAWABLE_XID(wid), sizeof(BITMAP), &bm);
07075 } else {
07076 hdc = ::GetDC((HWND)GDK_DRAWABLE_XID(wid));
07077 }
07078 memdc = ::CreateCompatibleDC(hdc);
07079
07080 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
07081 bmi.bmiHeader.biWidth = width;
07082 bmi.bmiHeader.biHeight = -1 * (int)(height);
07083 bmi.bmiHeader.biPlanes = 1;
07084 bmi.bmiHeader.biBitCount = 32;
07085 bmi.bmiHeader.biCompression = BI_RGB;
07086 bmi.bmiHeader.biSizeImage = 0;
07087 bmi.bmiHeader.biXPelsPerMeter = bmi.bmiHeader.biYPelsPerMeter = 0;
07088 bmi.bmiHeader.biClrUsed = 0;
07089 bmi.bmiHeader.biClrImportant = 0;
07090
07091 ximage = ::CreateDIBSection(hdc, (BITMAPINFO *) &bmi, DIB_RGB_COLORS, &bmbits, NULL, 0);
07092
07093 if (ximage && bmbits) {
07094 oldbitmap2 = ::SelectObject(memdc, ximage);
07095 ::BitBlt(memdc, x, y, width, height, hdc, 0, 0, SRCCOPY);
07096 ::SelectObject(memdc, oldbitmap2);
07097 }
07098 ::DeleteDC(memdc);
07099 if (GDK_DRAWABLE_TYPE(wid) == GDK_DRAWABLE_PIXMAP) {
07100 ::SelectObject(hdc, oldbitmap1);
07101 ::DeleteDC(hdc);
07102 } else {
07103 ::ReleaseDC((HWND)GDK_DRAWABLE_XID(wid), hdc);
07104 }
07105 if (ximage && bmbits) {
07106 ULong_t sz = width*height*4;
07107 ret = new unsigned char[sz];
07108 memcpy(ret, bmbits, sz);
07109 ::DeleteObject(ximage);
07110 }
07111 return ret;
07112 }
07113
07114
07115 Pixmap_t TGWin32::CreatePixmapFromData(unsigned char *bits, UInt_t width, UInt_t height)
07116 {
07117
07118
07119
07120
07121
07122
07123 BITMAPINFO bmp_info;
07124 bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
07125 bmp_info.bmiHeader.biWidth = width;
07126 bmp_info.bmiHeader.biHeight = -1 * (int)(height);
07127 bmp_info.bmiHeader.biPlanes = 1;
07128 bmp_info.bmiHeader.biBitCount = 32;
07129 bmp_info.bmiHeader.biCompression = BI_RGB;
07130 bmp_info.bmiHeader.biSizeImage = 0;
07131 bmp_info.bmiHeader.biClrUsed = 0;
07132 bmp_info.bmiHeader.biXPelsPerMeter = 0L;
07133 bmp_info.bmiHeader.biYPelsPerMeter = 0L;
07134 bmp_info.bmiHeader.biClrImportant = 0;
07135 bmp_info.bmiColors[0].rgbRed = 0;
07136 bmp_info.bmiColors[0].rgbGreen = 0;
07137 bmp_info.bmiColors[0].rgbBlue = 0;
07138 bmp_info.bmiColors[0].rgbReserved = 0;
07139
07140 HDC hdc = ::GetDC(NULL);
07141 HBITMAP hbitmap = ::CreateDIBitmap(hdc, &bmp_info.bmiHeader, CBM_INIT,
07142 (void *)bits, &bmp_info, DIB_RGB_COLORS);
07143 ::ReleaseDC(NULL, hdc);
07144
07145 SIZE size;
07146
07147
07148
07149 ::SetBitmapDimensionEx(hbitmap,width, height, &size);
07150
07151 return (Pixmap_t)gdk_pixmap_foreign_new((guint32)hbitmap);
07152 }
07153
07154
07155 Int_t TGWin32::AddPixmap(ULong_t pix, UInt_t w, UInt_t h)
07156 {
07157
07158 HBITMAP hBmp = reinterpret_cast<HBITMAP>(pix);
07159 SIZE sz = SIZE();
07160
07161 SetBitmapDimensionEx(hBmp, w, h, &sz);
07162 GdkPixmap *newPix = gdk_pixmap_foreign_new(reinterpret_cast<guint32>(hBmp));
07163
07164 Int_t wid = 0;
07165 for(; wid < fMaxNumberOfWindows; ++wid)
07166 if (!fWindows[wid].open)
07167 break;
07168
07169 if (wid == fMaxNumberOfWindows) {
07170 Int_t newSize = fMaxNumberOfWindows + 10;
07171
07172 fWindows = (XWindow_t *)TStorage::ReAlloc(fWindows, newSize * sizeof(XWindow_t),
07173 fMaxNumberOfWindows * sizeof(XWindow_t));
07174
07175 for (Int_t i = fMaxNumberOfWindows; i < newSize; ++i)
07176 fWindows[i].open = 0;
07177
07178 fMaxNumberOfWindows = newSize;
07179 }
07180
07181 fWindows[wid].open = 1;
07182 gCws = fWindows + wid;
07183 gCws->window = newPix;
07184 gCws->drawing = gCws->window;
07185 gCws->buffer = 0;
07186 gCws->double_buffer = 0;
07187 gCws->ispixmap = 1;
07188 gCws->clip = 0;
07189 gCws->width = w;
07190 gCws->height = h;
07191 gCws->new_colors = 0;
07192
07193 return wid;
07194 }
07195
07196
07197 Int_t TGWin32::AddWindow(ULong_t qwid, UInt_t w, UInt_t h)
07198 {
07199
07200
07201 Int_t wid;
07202
07203
07204 again:
07205 for (wid = 0; wid < fMaxNumberOfWindows; wid++) {
07206 if (!fWindows[wid].open) {
07207 fWindows[wid].open = 1;
07208 fWindows[wid].double_buffer = 0;
07209 gCws = &fWindows[wid];
07210 break;
07211 }
07212 }
07213
07214 if (wid == fMaxNumberOfWindows) {
07215 int newsize = fMaxNumberOfWindows + 10;
07216 fWindows =
07217 (XWindow_t *) TStorage::ReAlloc(fWindows,
07218 newsize * sizeof(XWindow_t),
07219 fMaxNumberOfWindows *
07220 sizeof(XWindow_t));
07221
07222 for (int i = fMaxNumberOfWindows; i < newsize; i++) {
07223 fWindows[i].open = 0;
07224 }
07225
07226 fMaxNumberOfWindows = newsize;
07227 goto again;
07228 }
07229
07230 gCws->window = gdk_window_foreign_new((guint32)qwid);
07231
07232 gCws->drawing = gCws->window;
07233 gCws->buffer = 0;
07234 gCws->double_buffer = 0;
07235 gCws->ispixmap = 0;
07236 gCws->clip = 0;
07237 gCws->width = w;
07238 gCws->height = h;
07239 gCws->new_colors = 0;
07240
07241 return wid;
07242 }
07243
07244
07245 void TGWin32::RemoveWindow(ULong_t qwid)
07246 {
07247
07248
07249 int wid;
07250
07251 SelectWindow((int)qwid);
07252
07253 if (gCws->buffer) {
07254 gdk_pixmap_unref(gCws->buffer);
07255 }
07256 if (gCws->new_colors) {
07257 gdk_colormap_free_colors((GdkColormap *) fColormap,
07258 (GdkColor *)gCws->new_colors, gCws->ncolors);
07259
07260 delete [] gCws->new_colors;
07261 gCws->new_colors = 0;
07262 }
07263
07264 GdiFlush();
07265 gCws->open = 0;
07266
07267 if (!fWindows) return;
07268
07269
07270 for (wid = 0; wid < fMaxNumberOfWindows; wid++) {
07271 if (fWindows[wid].open) {
07272 gCws = &fWindows[wid];
07273 return;
07274 }
07275 }
07276 gCws = 0;
07277 }
07278
07279
07280 void TGWin32::ShapeCombineMask(Window_t id, Int_t x, Int_t y, Pixmap_t mask)
07281 {
07282
07283
07284
07285
07286 gdk_window_shape_combine_mask((GdkWindow *)id, (GdkBitmap *) mask, x, y);
07287 }
07288
07289
07290 UInt_t TGWin32::ScreenWidthMM() const
07291 {
07292
07293
07294 return (UInt_t)gdk_screen_width_mm();
07295 }
07296
07297
07298
07299
07300 void TGWin32::DeleteProperty(Window_t win, Atom_t& prop)
07301 {
07302
07303
07304 HWND hWnd = (HWND)GDK_DRAWABLE_XID((GdkWindow *)win);
07305 Atom_t atom = (Atom_t)GetProp(hWnd,(LPCTSTR)MAKELONG(prop,0));
07306 if (atom != 0) {
07307 GlobalDeleteAtom(atom);
07308 }
07309 RemoveProp(hWnd,(LPCTSTR)MAKELONG(prop,0));
07310 }
07311
07312
07313 Int_t TGWin32::GetProperty(Window_t win, Atom_t prop, Long_t offset, Long_t len,
07314 Bool_t del, Atom_t req_type, Atom_t *act_type,
07315 Int_t *act_format, ULong_t *nitems, ULong_t *bytes,
07316 unsigned char **prop_list)
07317 {
07318
07319
07320
07321 HGLOBAL hdata;
07322 UChar_t *ptr, *data;
07323 UInt_t i, n, length;
07324
07325 HWND hWnd = (HWND)GDK_DRAWABLE_XID((GdkWindow *)win);
07326 if (hWnd == NULL)
07327 return 0;
07328
07329 Atom_t dndproxy = InternAtom("XdndProxy", kFALSE);
07330 Atom_t dndtypelist = InternAtom("XdndTypeList", kFALSE);
07331
07332 if (prop == dndproxy)
07333 return 0;
07334 if (prop == dndtypelist) {
07335 *act_type = XA_ATOM;
07336 *prop_list = (unsigned char *)GetProp(hWnd, (LPCTSTR)MAKELONG(prop,0));
07337 for (n = 0; prop_list[n]; n++);
07338 *nitems = n;
07339 return n;
07340 }
07341 else {
07342 if (!OpenClipboard((HWND)GDK_DRAWABLE_XID((GdkWindow *)win))) {
07343 return 0;
07344 }
07345 hdata = GetClipboardData(CF_PRIVATEFIRST);
07346 ptr = (UChar_t *)GlobalLock(hdata);
07347 length = GlobalSize(hdata);
07348 data = (UChar_t *)malloc(length + 1);
07349 for (i = 0; i < length; i++) {
07350 data[i] = ptr[i];
07351 }
07352 GlobalUnlock(hdata);
07353 CloseClipboard();
07354 *prop_list = data;
07355 *bytes = *nitems = length;
07356 return length;
07357 }
07358 return 0;
07359 }
07360
07361
07362 void TGWin32::ChangeActivePointerGrab(Window_t win, UInt_t mask, Cursor_t cur)
07363 {
07364
07365
07366 UInt_t xevmask;
07367 MapEventMask(mask, xevmask);
07368 if (cur == kNone)
07369 gdk_window_set_cursor((GdkWindow *) win, fCursors[kHand]);
07370 else
07371 gdk_window_set_cursor((GdkWindow *) win, (GdkCursor *)cur);
07372 }
07373
07374
07375 void TGWin32::ConvertSelection(Window_t win, Atom_t &sel, Atom_t &target,
07376 Atom_t &prop, Time_t &stamp)
07377 {
07378
07379
07380 HGLOBAL hdata;
07381
07382 static UINT gdk_selection_notify_msg =
07383 RegisterWindowMessage("gdk-selection-notify");
07384 HWND hWnd = (HWND)GDK_DRAWABLE_XID((GdkWindow *)win);
07385 if (!OpenClipboard((HWND)GDK_DRAWABLE_XID((GdkWindow *)win))) {
07386 return;
07387 }
07388 hdata = GetClipboardData(CF_PRIVATEFIRST);
07389 CloseClipboard();
07390 if (hdata == 0)
07391 return;
07392
07393
07394
07395 PostMessage(hWnd, gdk_selection_notify_msg, sel, target);
07396 }
07397
07398
07399 Bool_t TGWin32::SetSelectionOwner(Window_t owner, Atom_t &sel)
07400 {
07401
07402
07403 static UINT gdk_selection_request_msg =
07404 RegisterWindowMessage("gdk-selection-request");
07405 HWND hWnd = (HWND)GDK_DRAWABLE_XID((GdkWindow *)owner);
07406 OpenClipboard(hWnd);
07407 EmptyClipboard();
07408 CloseClipboard();
07409 if (owner) {
07410 ::PostMessage(hWnd, gdk_selection_request_msg, sel, 0);
07411 }
07412 return kTRUE;
07413 }
07414
07415
07416 void TGWin32::ChangeProperties(Window_t id, Atom_t property, Atom_t type,
07417 Int_t format, UChar_t *data, Int_t len)
07418 {
07419
07420
07421 HGLOBAL hdata;
07422 Int_t i, length;
07423 UChar_t *ptr;
07424
07425 if (data == 0 || len == 0)
07426 return;
07427 if (!OpenClipboard((HWND)GDK_DRAWABLE_XID((GdkWindow *)id))) {
07428 return;
07429 }
07430 hdata = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, len + 1);
07431 ptr = (UChar_t *)GlobalLock(hdata);
07432 for (i = 0; i < len; i++) {
07433 *ptr++ = *data++;
07434 }
07435 GlobalUnlock(hdata);
07436 SetClipboardData(CF_PRIVATEFIRST, hdata);
07437 CloseClipboard();
07438 }
07439
07440
07441 void TGWin32::SetTypeList(Window_t win, Atom_t prop, Atom_t *typelist)
07442 {
07443
07444
07445 SetProp((HWND)GDK_DRAWABLE_XID((GdkWindow *)win),
07446 (LPCTSTR)MAKELONG(prop,0),
07447 (HANDLE)typelist);
07448 }
07449
07450
07451 Window_t TGWin32::FindRWindow(Window_t root, Window_t dragwin, Window_t input,
07452 int x, int y, int maxd)
07453 {
07454
07455
07456
07457
07458 POINT screen_point, point;
07459 POINT cpt;
07460 RECT rect;
07461 HWND hwnd, hwndc;
07462 HWND hwndt;
07463 Window_t win, retwin = kNone;
07464 Atom_t version = 0;
07465 Atom_t dndaware = InternAtom("XdndAware", kFALSE);
07466
07467 cpt.x = x;
07468 cpt.y = y;
07469 hwnd = ::ChildWindowFromPointEx((HWND)GDK_DRAWABLE_XID((GdkWindow *)root),
07470 cpt, CWP_ALL);
07471 while (hwnd) {
07472 GetWindowRect(hwnd, &rect);
07473 if (PtInRect(&rect, cpt)) {
07474 if (GetProp(hwnd,(LPCTSTR)MAKELONG(dndaware,0))) {
07475 win = (Window_t) gdk_xid_table_lookup(hwnd);
07476 if (win && win != dragwin && win != input)
07477 return win;
07478 }
07479 Bool_t done = kFALSE;
07480 hwndt = hwnd;
07481 while (!done) {
07482 point = cpt;
07483 ::MapWindowPoints(NULL, hwndt, &point, 1);
07484 hwndc = ChildWindowFromPoint (hwndt, point);
07485 if (GetProp(hwnd,(LPCTSTR)MAKELONG(dndaware,0))) {
07486 win = (Window_t) gdk_xid_table_lookup(hwndc);
07487 if (win && win != dragwin && win != input)
07488 return win;
07489 }
07490 if (hwndc == NULL)
07491 done = TRUE;
07492 else if (hwndc == hwndt)
07493 done = TRUE;
07494 else
07495 hwndt = hwndc;
07496 if (GetProp(hwndt,(LPCTSTR)MAKELONG(dndaware,0))) {
07497 win = (Window_t) gdk_xid_table_lookup(hwndt);
07498 if (win && win != dragwin && win != input)
07499 return win;
07500 }
07501 }
07502 }
07503 hwnd = GetNextWindow(hwnd, GW_HWNDNEXT);
07504 }
07505 return kNone;
07506 }
07507
07508
07509 Bool_t TGWin32::IsDNDAware(Window_t win, Atom_t *typelist)
07510 {
07511
07512
07513
07514 if (!win) return kFALSE;
07515
07516 Atom_t version = 0;
07517 Atom_t dndaware = InternAtom("XdndAware", kFALSE);
07518 HWND window = (HWND)GDK_DRAWABLE_XID((GdkWindow *)win);
07519 while (window) {
07520 version = (Atom_t)GetProp(window,(LPCTSTR)MAKELONG(dndaware,0));
07521 if (version) return kTRUE;
07522 window = ::GetParent(window);
07523 }
07524 return kFALSE;
07525 }
07526
07527
07528 void TGWin32::SetDNDAware(Window_t id, Atom_t *typelist)
07529 {
07530
07531
07532
07533 int n;
07534 if (!id) return;
07535
07536 DWORD dwStyle = GetWindowLong((HWND)GDK_DRAWABLE_XID((GdkWindow *)id),
07537 GWL_EXSTYLE);
07538 SetWindowLong((HWND)GDK_DRAWABLE_XID((GdkWindow *)id), GWL_EXSTYLE,
07539 dwStyle | WS_EX_ACCEPTFILES);
07540 Atom_t dndaware = InternAtom("XdndAware", kFALSE);
07541 SetProp((HWND)GDK_DRAWABLE_XID((GdkWindow *)id),
07542 (LPCTSTR)MAKELONG(dndaware,0),
07543 (HANDLE)XDND_PROTOCOL_VERSION);
07544
07545 if (typelist == 0)
07546 return;
07547 for (n = 0; typelist[n]; n++);
07548 Atom_t dndtypelist = InternAtom("XdndTypeList", kFALSE);
07549 SetProp((HWND)GDK_DRAWABLE_XID((GdkWindow *)id),
07550 (LPCTSTR)MAKELONG(dndtypelist,0),
07551 (HANDLE)typelist);
07552
07553 }
07554
07555
07556 void TGWin32::SetUserThreadId(ULong_t id)
07557 {
07558
07559
07560
07561 if (id == 0) {
07562 TGWin32ProxyBase::fgMainThreadId = ((TWinNTSystem*)gSystem)->GetGUIThreadId();
07563 }
07564 else {
07565 TGWin32ProxyBase::fgUserThreadId = id;
07566 }
07567 }
07568